R is a language specialized for statistics.
This is a quick guide to start using R from Emacs:
1. Install R (http://cran.r-project.org/manuals.html)
2. Install ESS (Emacs Speaks Statistics) package for Emacs. It is available as a package in most distros:
In Ubuntu
$ sudo apt-get install ess
To install in your environment, check Downloads in ESS site: http://ess.r-project.org
3. Open .R file to turn on ESS mode in Emacs
4. To open R shell in inferior mode:
M-x inferior-ess
This will start a shell where you can run R interactively.
5. To evaluate an expression in buffer in R console, select the expression or block in Emacs (Ctrl+Space and arrow keys) and C-c C-r
Follow the instructions here to evaluate using just Shift+Enter:
http://www.kieranhealy.org/blog/archives/2009/10/12/make-shift-enter-do-a-lot-in-ess/
Saturday, September 3, 2011
Tuesday, July 19, 2011
If you can't solve a problem, then there is an easier problem you can't solve
I was trying to solve a problem of splitting a percentage into multiple percentages for entities based on their weights. For a long time, i was convinced that this was a weighted average/percentage problem. And then i remembered what Polya says in his book "How to Solve it": If you can't solve a problem, then there is an easier problem you can't solve: find it
I feel like a fifth grader now for asking this and this on http://math.stackexchange.com and not seeing the obvious solution. To avoid further humiliation on the internet, i used a notepad to find and solve an easier problem. See if you can solve it.
Problem 1:
A marketing company with 3 salesmen A,B,C has total revenue of 10,000 $.
A, B, C have the following revenues:
A = 2000 $
B = 3000 $
C = 5000 $
How will the marketing company increase revenues by 10 %?
Solution 1.1:
By increasing the revenues of A,B,C by 10%
A = 2200 $
B = 3300 $
C = 5500 $
Total revenue = 11000 $ = 10 %
Solution 1.2:
By increasing the revenue of A by 1000 $ or 10 % of total
A = 2000 $ + 1000 $ = 3000 $
Total revenue = 11000 $ = 10 %
Solution 1.3:
Assuming dA, dB, dC denote the increase in revenues for A,B,C, all possible solutions are given by the algebraic equation:
dA + dB + dC = 1000 $
Solution 1.4:
A reasonably achievable solution can be obtained by taking the weighted percentages of Total revenues:
dA = 10 % * 2000 / 10000 = 2 % * 10000= 200 $
dB = 10 % * 3000 / 10000 = 3 % * 10000= 300 $
dC = 10 % * 5000 / 10000 = 5 % * 10000= 500 $
Increase in Revenue = 1000 $ = 10 %
Problem 2:
Revenues have two parts - Income and Expense
For A = 2000 $
Ia = 80% = 1600 $
Ea = 20% = 400 $
For B = 3000 $:
Ib = 70% = 2100 $
Eb = 30% = 900 $
For C = 5000 $:
Ic = 60% = 3000 $
Ec = 40% = 2000 $
Total income = 6700 $ = 67 %
Total expense = 3300 $ = 33 %
How will the marketing company increase only Incomes by 10 %?
Solution 2.1
A simpler solution is to increase Ia, Ib, Ic by 10% each.
Ia = 1600 + 160 = 1760 $
Ib = 2100 + 210 = 2310 $
Ic = 3000 + 300 = 3300 $
Total income = 6700 + 670 = 10 % increase
Solution 2.2
Another simpler solution is to increase only Ia by 670 $ or 10 % of total
Ia = 1600 + 670
Total income = 6700 + 670 = 10 % increase
Solution 2.3:
Assuming dIa, dIb, dIc denote the increase in Income for A,B,C, the solution is given by the algebraic equation with 3 unknowns:
dIa + dIb + dIc = 670
Solution 2.4
A reasonably achievable solution can be obtained by taking the weighted percentages of total income:
dIa = 10 % * 2000 / 10000 = 2 % of 6700= 134 $
dIb = 10 % * 3000 / 10000 = 3 % of 6700= 201 $
dIc = 10 % * 5000 / 10000 = 5 % of 6700= 335 $
Increase in Income = 670 $ = 10 %
Problem 3:
Retrospectively, How could the marketing company have increased incomes by 10 % and decreased expenses by 10 % for the same revenues last year?
Solution 3.1:
Solution 2.3 increases only total income by 10 % keeping the total expense constant.
This results in the proportion of income and expense not being 67 % + 33 % anymore
To increase income by 10 % and decrease expense by 10 % for the same total revenues last year
Total income (old) = 6700 $ = 67 %
Total expense (old) = 3300 $ = 33 %
Total revenue (old) = 6700 + 3300 = 10000 $
Total income (new) = 77 % = 7700 $
Total income (new) = 23 % = 2300 $
Total revenue (new = 7700 + 2300 = 10000 $
The solution is given by the solutions to the 2 equations with 6 unknowns:
dIa + dIb + dIc = New income - Old income = 77% * 10,000 - 6700 = 1000
dEa + dEb + dEc = New expense - Old expense = 23% * 10,000 - 3300 = -1000
Solution 3.2
A reasonably achievable solution can be obtained by taking the weighted percentage of total Increase/Decrease in Income/Expense
Total income increase = 1000 $
Total expense decrease = -1000 $
By using weighted percentages of total increase in income:
dIa = 2 % of +1000 = 200 $
dIb = 3% of +1000 = 300 $
dIc = 5% of +1000 = 500 $
dI = +1000 = +10%
By using weighted percentages of total decrease in expense:
dEa = 2 % of -1000 = -200 $
dEb = 3% of -1000 = -300 $
dEc = 5% of -1000 = -500 $
dE = -1000 = -10%
I feel like a fifth grader now for asking this and this on http://math.stackexchange.com and not seeing the obvious solution. To avoid further humiliation on the internet, i used a notepad to find and solve an easier problem. See if you can solve it.
Problem 1:
A marketing company with 3 salesmen A,B,C has total revenue of 10,000 $.
A, B, C have the following revenues:
A = 2000 $
B = 3000 $
C = 5000 $
How will the marketing company increase revenues by 10 %?
Solution 1.1:
By increasing the revenues of A,B,C by 10%
A = 2200 $
B = 3300 $
C = 5500 $
Total revenue = 11000 $ = 10 %
By increasing the revenue of A by 1000 $ or 10 % of total
A = 2000 $ + 1000 $ = 3000 $
Total revenue = 11000 $ = 10 %
Solution 1.3:
Assuming dA, dB, dC denote the increase in revenues for A,B,C, all possible solutions are given by the algebraic equation:
dA + dB + dC = 1000 $
Solution 1.4:
A reasonably achievable solution can be obtained by taking the weighted percentages of Total revenues:
dA = 10 % * 2000 / 10000 = 2 % * 10000= 200 $
dB = 10 % * 3000 / 10000 = 3 % * 10000= 300 $
dC = 10 % * 5000 / 10000 = 5 % * 10000= 500 $
Increase in Revenue = 1000 $ = 10 %
Problem 2:
Revenues have two parts - Income and Expense
For A = 2000 $
Ia = 80% = 1600 $
Ea = 20% = 400 $
For B = 3000 $:
Ib = 70% = 2100 $
Eb = 30% = 900 $
For C = 5000 $:
Ic = 60% = 3000 $
Ec = 40% = 2000 $
Total income = 6700 $ = 67 %
Total expense = 3300 $ = 33 %
How will the marketing company increase only Incomes by 10 %?
Solution 2.1
A simpler solution is to increase Ia, Ib, Ic by 10% each.
Ia = 1600 + 160 = 1760 $
Ib = 2100 + 210 = 2310 $
Ic = 3000 + 300 = 3300 $
Total income = 6700 + 670 = 10 % increase
Solution 2.2
Another simpler solution is to increase only Ia by 670 $ or 10 % of total
Ia = 1600 + 670
Total income = 6700 + 670 = 10 % increase
Solution 2.3:
Assuming dIa, dIb, dIc denote the increase in Income for A,B,C, the solution is given by the algebraic equation with 3 unknowns:
dIa + dIb + dIc = 670
Solution 2.4
A reasonably achievable solution can be obtained by taking the weighted percentages of total income:
dIa = 10 % * 2000 / 10000 = 2 % of 6700= 134 $
dIb = 10 % * 3000 / 10000 = 3 % of 6700= 201 $
dIc = 10 % * 5000 / 10000 = 5 % of 6700= 335 $
Increase in Income = 670 $ = 10 %
Problem 3:
Retrospectively, How could the marketing company have increased incomes by 10 % and decreased expenses by 10 % for the same revenues last year?
Solution 3.1:
Solution 2.3 increases only total income by 10 % keeping the total expense constant.
This results in the proportion of income and expense not being 67 % + 33 % anymore
To increase income by 10 % and decrease expense by 10 % for the same total revenues last year
Total income (old) = 6700 $ = 67 %
Total expense (old) = 3300 $ = 33 %
Total revenue (old) = 6700 + 3300 = 10000 $
Total income (new) = 77 % = 7700 $
Total income (new) = 23 % = 2300 $
Total revenue (new = 7700 + 2300 = 10000 $
The solution is given by the solutions to the 2 equations with 6 unknowns:
dIa + dIb + dIc = New income - Old income = 77% * 10,000 - 6700 = 1000
dEa + dEb + dEc = New expense - Old expense = 23% * 10,000 - 3300 = -1000
Solution 3.2
A reasonably achievable solution can be obtained by taking the weighted percentage of total Increase/Decrease in Income/Expense
Total income increase = 1000 $
Total expense decrease = -1000 $
By using weighted percentages of total increase in income:
dIa = 2 % of +1000 = 200 $
dIb = 3% of +1000 = 300 $
dIc = 5% of +1000 = 500 $
dI = +1000 = +10%
By using weighted percentages of total decrease in expense:
dEa = 2 % of -1000 = -200 $
dEb = 3% of -1000 = -300 $
dEc = 5% of -1000 = -500 $
dE = -1000 = -10%
Sunday, June 12, 2011
Methodology X and Goats
I've worked in a CMMi certified workplace, where they spend more time preparing for CMMi certification than doing the actual work. And when they do get to do the actual work it'll have more defects than the intended set of problems it was meant to solve. And to fix those defects, you fill in more fields in defect management software than the lines of code required to do the fix. And once it is fixed, it had to be code reviewed by people who knew more about code reviews than coding. Long story short, It's hard to work like this unless you want to make a career out of CMMi.
After this, I worked in an XP development workplace. Most of the stuff made sense for effective teamwork and delivery. There were no documents, code reviews, audits and NO defects. And most of all, the people who used the software were happy, just like the developers who worked on the codebase.
I've always had the perception that Agile was just "common sense" and it eliminates the Waste called Management (Yes, you heard it right Deming, Drucker et al) in software development. I came across a post from a friend validating my perception with an interesting story (http://vinodkumaar.wordpress.com/2011/06/12/agility/):
The goat metaphor was interesting and i'm going to take it too far to make fun of different methodologies:
A CMMi goat will prepare a process document spreadsheet on how it plans to jump.
A six sigma goat will prove that only 3.4 out of one million goats die in that situation.
A scrum goat will go to a weekend scrum certification workshop and become a scrum master before it jumps.
An XP goat prefers to jump in pairs and always tests before jumping.
An agile goat just jumps.
But, if agile is just common sense, why are there so many ways of doing agile? Common sense isn't so common after all and not everybody has an equal measure of common sense.
A methodology/process is just a guideline for solving a problem and not a solution. Just use it as a guideline with lots of common sense. To paraphrase, Rich Hickey's thoughts on Methodologies from his talk Hammock driven development:
P.S:
Why didn't you make fun of RUP, Lean, Kanban or Methodology Y?
I just ran out of jokes. Please leave your methodology jokes in the comments section below to be added.
After this, I worked in an XP development workplace. Most of the stuff made sense for effective teamwork and delivery. There were no documents, code reviews, audits and NO defects. And most of all, the people who used the software were happy, just like the developers who worked on the codebase.
I've always had the perception that Agile was just "common sense" and it eliminates the Waste called Management (Yes, you heard it right Deming, Drucker et al) in software development. I came across a post from a friend validating my perception with an interesting story (http://vinodkumaar.wordpress.com/2011/06/12/agility/):
A hunter watches a mountain goat grazing on the pastures on the side of a highway. A speeding truck loses control and starts veering towards the grazing goat, in split seconds it jumps off to a safe place. The hunter’s kid who was watching all this asked his dad, “Did the goat escape because it is agile?”. The hunter replied “It is just common sense to avoid a speeding truck”.
The goat metaphor was interesting and i'm going to take it too far to make fun of different methodologies:
A CMMi goat will prepare a process document spreadsheet on how it plans to jump.
A six sigma goat will prove that only 3.4 out of one million goats die in that situation.
A scrum goat will go to a weekend scrum certification workshop and become a scrum master before it jumps.
An XP goat prefers to jump in pairs and always tests before jumping.
An agile goat just jumps.
But, if agile is just common sense, why are there so many ways of doing agile? Common sense isn't so common after all and not everybody has an equal measure of common sense.
A methodology/process is just a guideline for solving a problem and not a solution. Just use it as a guideline with lots of common sense. To paraphrase, Rich Hickey's thoughts on Methodologies from his talk Hammock driven development:
If you practice Methodology X, you get good at Methodology X. If you practice problem solving, you get good at the general idea of solving problems... We as software engineers, are in the business of solving problems.
P.S:
Why didn't you make fun of RUP, Lean, Kanban or Methodology Y?
I just ran out of jokes. Please leave your methodology jokes in the comments section below to be added.
Friday, May 20, 2011
Swank Clojure in seconds with Maven (Link)
Clojure is at the end of the day Java. Whether you love it or hate it, Maven is here to stay for java builds. Here is a very good article by learningclojure.com on how to get Clojure REPL or Swank Clojure up and running in seconds with a simple Maven pom.xml file. Also, If you've wondered what goes on beneath leiningen, this is a good place to start:
http://www.learningclojure.com/2010/08/clojure-emacs-swank-slime-maven-maven.html
Now, starting a REPL is as simple as:
$ mvn clojure:repl
Starting Swank server for Emacs is as simple as:
$ mvn clojure:swank
http://www.learningclojure.com/2010/08/clojure-emacs-swank-slime-maven-maven.html
Now, starting a REPL is as simple as:
$ mvn clojure:repl
Starting Swank server for Emacs is as simple as:
$ mvn clojure:swank
Saturday, May 14, 2011
Scheme in Emacs
If you're reading SICP or Little Schemer or any Scheme book and find MIT Scheme REPL not too comfortable, here is a brief guide to start hacking Scheme in Emacs:
1. Install MIT Scheme (using your platform's package manager)
$ sudo apt-get install mit-scheme
2. Emacs comes with inbuilt support for Lisp/Scheme. Open Scheme source file (*.ss or *.scm) for Scheme major mode to kick in.
3. M-x run-scheme
This will start MIT Scheme REPL in inferior-mode in a buffer.
4. With the REPL open, Open another buffer for your Scheme source code (using C-x 2 or C-x 3)
5. Now you can directly eval code from your buffer. Just move cursor to the end of any expression (C-e) and evaluate it using C-x C-e
1. Install MIT Scheme (using your platform's package manager)
$ sudo apt-get install mit-scheme
2. Emacs comes with inbuilt support for Lisp/Scheme. Open Scheme source file (*.ss or *.scm) for Scheme major mode to kick in.
3. M-x run-scheme
This will start MIT Scheme REPL in inferior-mode in a buffer.
4. With the REPL open, Open another buffer for your Scheme source code (using C-x 2 or C-x 3)
5. Now you can directly eval code from your buffer. Just move cursor to the end of any expression (C-e) and evaluate it using C-x C-e
Thursday, May 5, 2011
Clojure in Emacs
This is a brief guide to setting up and hacking Clojure in Emacs.
1. Install Emacs.
Install Emacs23 if you're on a Linux and Carbon Emacs if you're on OSX. Aquamacs is discouraged due to issues with Emacs starter kit.
2. Tutorial
Take an hour and work through the tutorial to get comfortable with Emacs shortcuts. It'll be the most productive hour you ever invested. Grab a cheatsheet and get used to it by coding away in your favorite language.
3. Get the Emacs starter kit. It comes with major/minor modes for most languages.
If you're on OSX, Grab this version by topfunky for Carbon Emacs:
https://github.com/topfunky/emacs-starter-kit
If you're on Linux, clone it from the original fork here by technomancy:
https://github.com/technomancy/emacs-starter-kit
After cloning the started kit, make it your ~/.emacs.d/ folder
4. Install Emacs packages for Clojure
4.1 M-x package-list-packages
to list available packages
(If this doesn't work, your Emacs starter kit isn't working)
4.2 Select the following packages by pressing I to mark for installation
clojure-mode
clojure-test-mode
slime
slime-repl
4.3 Press X to install selected packages
5. Inferior mode, SLIME and SWANK
A small digression on Inferior mode, Superior mode and Swank.
Emacs is a text editor which can be extended using EmacsLisp.
Inferior mode is how you eval snippet of code directly from editor in a Lisp (configured in inferior-lisp-program by the major mode you currently are in).
SLIME or Superior Lisp Interaction mode for Emacs is how you start a REPL in Emacs.
Emacs being just a text editor can't really eval Lisp code unless it's Emacs lisp. The way inferior mode and superior mode really work is through Swank which is sort of a REPL server to which Emacs connects.
5.1 To eval an expression in inferior-mode, just move to the end of a Clojure expression and press C-x C-e.
5.2 To start Swank server for Clojure REPL, you need to install Swank-Clojure:
5.2.1 Install Leiningen (https://github.com/technomancy/leiningen)
Leiningen is a build tool for Clojure. Leiningen can be used to install Swank clojure as a plugin and start the Swank server for Emacs
To install Lein, Download the script, make it executable and run it
$ wget https://github.com/technomancy/leiningen/raw/stable/bin/lein
$ sudo cp lein /usr/bin
$ sudo chmod +x /usr/bin/lein
$ lein
5.2.2 Install Swank clojure (https://github.com/technomancy/swank-clojure)
After installing Lein, Install Swank clojure as a plugin:
$ lein plugin install swank-clojure 1.3.0
Lein installs plugins in ~/.lein/bin. swank-clojure startup script is created there.
Add ~/.lein/bin to your path
5.2.3 Start Swank server and connect from Emacs
$ swank-clojure
starts Swank server for Clojure REPL
Start Clojure REPL in Emacs by connecting to Swank server. Accept defaults for host and port
M-x slime-connect
Now ogle at the most elegant editor you'll ever see and hack away in the most elegant language you'll ever write code in.
(Reference: http://technomancy.us/126)
1. Install Emacs.
Install Emacs23 if you're on a Linux and Carbon Emacs if you're on OSX. Aquamacs is discouraged due to issues with Emacs starter kit.
2. Tutorial
Take an hour and work through the tutorial to get comfortable with Emacs shortcuts. It'll be the most productive hour you ever invested. Grab a cheatsheet and get used to it by coding away in your favorite language.
3. Get the Emacs starter kit. It comes with major/minor modes for most languages.
If you're on OSX, Grab this version by topfunky for Carbon Emacs:
https://github.com/topfunky/emacs-starter-kit
If you're on Linux, clone it from the original fork here by technomancy:
https://github.com/technomancy/emacs-starter-kit
After cloning the started kit, make it your ~/.emacs.d/ folder
4. Install Emacs packages for Clojure
4.1 M-x package-list-packages
to list available packages
(If this doesn't work, your Emacs starter kit isn't working)
4.2 Select the following packages by pressing I to mark for installation
clojure-mode
clojure-test-mode
slime
slime-repl
4.3 Press X to install selected packages
5. Inferior mode, SLIME and SWANK
A small digression on Inferior mode, Superior mode and Swank.
Emacs is a text editor which can be extended using EmacsLisp.
Inferior mode is how you eval snippet of code directly from editor in a Lisp (configured in inferior-lisp-program by the major mode you currently are in).
SLIME or Superior Lisp Interaction mode for Emacs is how you start a REPL in Emacs.
Emacs being just a text editor can't really eval Lisp code unless it's Emacs lisp. The way inferior mode and superior mode really work is through Swank which is sort of a REPL server to which Emacs connects.
5.1 To eval an expression in inferior-mode, just move to the end of a Clojure expression and press C-x C-e.
5.2 To start Swank server for Clojure REPL, you need to install Swank-Clojure:
5.2.1 Install Leiningen (https://github.com/technomancy/leiningen)
Leiningen is a build tool for Clojure. Leiningen can be used to install Swank clojure as a plugin and start the Swank server for Emacs
To install Lein, Download the script, make it executable and run it
$ wget https://github.com/technomancy/leiningen/raw/stable/bin/lein
$ sudo cp lein /usr/bin
$ sudo chmod +x /usr/bin/lein
$ lein
5.2.2 Install Swank clojure (https://github.com/technomancy/swank-clojure)
After installing Lein, Install Swank clojure as a plugin:
$ lein plugin install swank-clojure 1.3.0
Lein installs plugins in ~/.lein/bin. swank-clojure startup script is created there.
Add ~/.lein/bin to your path
5.2.3 Start Swank server and connect from Emacs
$ swank-clojure
starts Swank server for Clojure REPL
Start Clojure REPL in Emacs by connecting to Swank server. Accept defaults for host and port
M-x slime-connect
Now ogle at the most elegant editor you'll ever see and hack away in the most elegant language you'll ever write code in.
(Reference: http://technomancy.us/126)
Monday, November 16, 2009
Litexte
Litexte is a Textile parser which i wrote to see how far i can go with Regex patterns and to exercise my lazy right brain. In this blogpost ill be illustrating how to create a parser in Ruby for Textile.
Textile is a light-weight markup language like Markdown. RedCloth is a well-known library for parsing Textile markup in Ruby. What's the fun in using an existing library? Lets weave our very own Textile parser with lots of Regex awesomeness just for fun.
Checkout this Textile quick reference written by _why. Click here for a sample textile input which will be used to build the Parser
Textile markup can be categorized and parsed in the following order:
1. Headers and Blockquotes
Headers are represented with a begin marker, followed by a . and content.
input.gsub!(/h1\.(.*?)\n/,'<h1>\1</h1>')
input.gsub!(/h2\.(.*?)\n/,'<h2>\1</h2>')
input.gsub!(/h3\.(.*?)\n/,'<h3>\1</h3>')
input.gsub!(/bq\.(.*?)\n/,'<blockquote>\1</blockquote>')
2. Delimited tags
Delimited markups have a begin and end marker with the content in the middle. Most of Textile markups fall in this category.
input.gsub!(/\_{2}(.*?)\_{2}/,'<i>\1</i>')
input.gsub!(/\*{2}(.*?)\*{2}/,'<b>\1</b>')
input.gsub!(/\?{2}(.*?)\?{2}/,'<cite>\1</cite>')
input.gsub!(/\_{1}(.*?)\_{1}/,'<em>\1</em>')
input.gsub!(/\*{1}(.+?)\*{1}/,'<strong>\1</strong>')
input.gsub!(/\-{1}(.*?)\-{1}/,'<del>\1</del>')
input.gsub!(/\+{1}(.*?)\+{1}/,'<ins>\1</ins>')
input.gsub!(/\^{1}(.*?)\^{1}/,'<sup>\1</sup>')
input.gsub!(/\~{1}(.*?)\~{1}/,'<sub>\1</sub>')
3. Links, Images , Superscript, Subscript
Links, Images, Superscript, Subscript tags etc dont follow symmetric patterns, but can still be parsed easily with simple regexes
input.gsub!(/"(\w+)":(\S+)/,'<a href="\2">\1</a>')
input.gsub!(/\!{1}(.*?)\!{1}/,'<img src="\1"/>')
4. Span and P tags
Span and P tags are a little tricky because there are several variants with classes, ids, style etc like:
%Ruby is awesome%
Ruby is awesome
%{color:blue}Regex is awesome%
Regex is awesome
Ruby Regexes can be used with blocks, which is a very powerful feature for this kind of conditional substitution. It suits both a simple span tag and p tag with numerous variants. Check out the below regex substitution with blocks for span and p:
input.gsub!(/\%{1}(\{(.*)\})?(.*?)\%{1}/) do
style = $1 ? " style=\"#{$2}\" " : ''
"<span#{style}>#{$3}</span>"
end
input.gsub!(/p([\<\>\=]+)?(\((.*)\))?(\{(.*)\})?(\[(.*)\])?\.(.*?)\n/) do
aligns = {'<' => 'left', '>' => 'right', '=' => 'center', '<>' => 'justify'}
align = $1 ? " text-align: #{aligns[$1]};" : ""
styles = $5 || ""
style = (align + styles).empty? ? "" : " style=\"#{align}#{styles}\""
lang = $7 ? " lang=\"#{$7}\"" : ""
text = $8
mdata = $3 ? $3.match(/(\w+)?#?(\w+)?/) : []
_class = mdata[1] ? " class=\"#{mdata[1]}\"" : ""
_id = mdata[2] ? " id=\"#{mdata[2]}\"" : ""
"<p#{_id}#{_class}#{style}#{lang}>#{text}</p>"
end
5. Tables
|_. Name |_. Age |
|John |20 |
|Bill |25 |
For Tables you need a way to block substitute each table in the markup incase there are multiple tables. Otherwise its very straightforward:
def parse_table(table)
header = /^\_\./
out = "<table>"
table.each do |row|
out += "<tr>"
row.split('|').reject {|t| t.chomp.empty?}.each do |cell|
if cell =~ header
out += "<th>#{cell.sub(header,'')}</th>"
else
out += "<td>#{cell}</td>"
end
end
out += "</tr>"
end
out += "</table>"
end
6. Ordered and Unordered Lists
# Languages
## Ruby
## Python
# Frameworks
## Rails
Lists in addition to being multiple can also be nested, which requires a recursive solution, to either spit out the list content or to parse a sublist. The solution is not follow Ruby idioms because each and sublisting don't work very well.
def parse_list(list)
items = list.scan(/^#+.*?\n/).map(&:chomp).collect {|item| item =~ /(#+)(.*)/; [$1,$2]}
parse_list_items(items, symbol)
end
def parse_list_items(items, start = 0)
list_out = "<ol>"
i = 0
while(i < items.length)
level, item = items[i]
if level.length-start == 1
list_out += "<li>#{item}</li>"
i += 1
else
j = i + (items[i,items.size].find_index {|e| e[0].length == start+1} || items.length)
list_out += parse_list_items(items[i,j-1], start+1)
i += (j-1)
end
end
list_out += "</ol>"
end
Subscribe to:
Posts (Atom)