Theorem Environments

Implement amsthm-like Theorem environments with Maruku.
Support is based on Maruku "div"s with special class-names.
Classes
    num_*
produce numbered environments, and

    un_*

produce un-numbered environments, where * is one of

   theorem     (for Theorem)
   lemma       (for Lemma)
   prop        (for Proposition)
   cor         (for Corollary)
   def         (for Definition)
   example     (for Example)
   remark      (for Remark)
   note        (for Note)

In addition, the class

   proof

produces a Proof environment.

The LaTeX export works as expected, and these also work in the S5 view.

Bumped version number.
This commit is contained in:
Jacques Distler 2008-10-17 16:26:17 -05:00
parent 6f3e9a9e17
commit 34082fbf94
12 changed files with 175 additions and 16 deletions

View file

@ -232,7 +232,7 @@ end
module Instiki module Instiki
module VERSION #:nodoc: module VERSION #:nodoc:
MAJOR = 0 MAJOR = 0
MINOR = 14 MINOR = 15
TINY = 0 TINY = 0
SUFFIX = '(MML+)' SUFFIX = '(MML+)'
PRERELEASE = 'pre' # false PRERELEASE = 'pre' # false

View file

@ -66,7 +66,7 @@
<% if @show_footer %> <% if @show_footer %>
<div id="footer"> <div id="footer">
<div>This site is running on <a href="http://instiki.org">Instiki</a> <a href="http://golem.ph.utexas.edu/instiki/show/HomePage"><%= "#{Instiki::VERSION::STRING}" %></a></div> <div>This site is running on <a href="http://golem.ph.utexas.edu/instiki/show/HomePage">Instiki <%= "#{Instiki::VERSION::STRING}" %></a></div>
<div>Powered by <a href="http://rubyonrails.com/">Ruby on Rails</a> <%= "#{Rails::VERSION::STRING}" %></div> <div>Powered by <a href="http://rubyonrails.com/">Ruby on Rails</a> <%= "#{Rails::VERSION::STRING}" %></div>
</div> </div>
<% end %> <% end %>

View file

@ -21,6 +21,7 @@
<!-- S5 JS --> <!-- S5 JS -->
<script src="/s5/ui/core/slides.js" type="text/javascript"></script> <script src="/s5/ui/core/slides.js" type="text/javascript"></script>
<script src="/javascripts/prototype.js" type="text/javascript"></script>
</head> </head>
<body> <body>

View file

@ -3,6 +3,7 @@
\usepackage{amsmath} \usepackage{amsmath}
\usepackage{amsfonts} \usepackage{amsfonts}
\usepackage{amssymb} \usepackage{amssymb}
\usepackage{amsthm}
\usepackage{graphicx} \usepackage{graphicx}
\usepackage{color} \usepackage{color}
\usepackage{ucs} \usepackage{ucs}
@ -200,6 +201,27 @@
\newcommand{\statusline}[2]{#2} \newcommand{\statusline}[2]{#2}
\newcommand{\toggle}[2]{#1} \newcommand{\toggle}[2]{#1}
% Theorem Environments
\theoremstyle{plain}
\newtheorem{theorem}{Theorem}
\newtheorem{lemma}{Lemma}
\newtheorem{prop}{Proposition}
\newtheorem{cor}{Corollary}
\newtheorem*{utheorem}{Theorem}
\newtheorem*{ulemma}{Lemma}
\newtheorem*{uprop}{Proposition}
\newtheorem*{ucor}{Corollary}
\theoremstyle{definition}
\newtheorem{def}{Definition}
\newtheorem{example}{Example}
\newtheorem*{udef}{Definition}
\newtheorem*{uexample}{Example}
\theoremstyle{remark}
\newtheorem{remark}{Remark}
\newtheorem{note}{Note}
\newtheorem*{uremark}{Remark}
\newtheorem*{unote}{Note}
%------------------------------------------------------------------- %-------------------------------------------------------------------
\begin{document} \begin{document}

View file

@ -18,6 +18,30 @@ function extractBlockquoteCitations() {
} }
} }
} }
function fixRunIn() {
// work around lack of gecko support for display:run-in
var re = /^num_|\s+num_|^un_|\s+un_|proof/;
$$('div > h6').each(function(element) {
if(re.test($(element.parentNode).className)) {
var new_span = new Element('span').update(element.textContent);
new_span.addClassName('theorem_label');
var next_el = element.next().firstChild;
next_el.parentNode.insertBefore(new_span, next_el);
var period = new Element('span').update('. ');
next_el.parentNode.insertBefore(period, next_el);
element.remove();
}
});
// add tombstone to proof, since gecko doesn't support :last-child properly
$$('div.proof').each(function(element) {
var l = element.childElements().length -1;
var span = new Element('span').update('\u00a0\u00a0\u25ae');
element.childElements()[l].insert(span);
});
}
window.onload = function (){ window.onload = function (){
extractBlockquoteCitations(); extractBlockquoteCitations();
fixRunIn();
}; };

View file

@ -17,3 +17,21 @@ table.plaintable {
margin-left:30px; margin-left:30px;
} }
.noborder td, .noborder th {border:0} .noborder td, .noborder th {border:0}
body {counter-reset: theorem lemma proposition corollary example remark}
.un_theorem *, .num_theorem *,
.un_lemma *, .num_lemma *,
.un_prop *, .num_prop *,
.un_cor *, .num_cor * {font-style: italic}
span.theorem_label {font-style:normal; font-weight:bold;}
.num_theorem .theorem_label:after {
content: " " counter(theorem); counter-increment: theorem;}
.num_lemma .theorem_label:after {
content: " " counter(lemma); counter-increment: lemma;}
.num_prop .theorem_label:after {
content: " " counter(proposition); counter-increment: proposition;}
.num_cor .theorem_label:after {
content: " " counter(corollary); counter-increment: corollary;}
.num_example .theorem_label:after {
content: " " counter(example); counter-increment: example;}
.num_remark .theorem_label:after {
content: " " counter(remark); counter-increment: remark;}

View file

@ -809,6 +809,29 @@ function windowChange() {
fontScale(); fontScale();
} }
function fixRunIn() {
// work around lack of gecko support for display:run-in
var re = /^num_|\s+num_|^un_|\s+un_|proof/;
$$('div > h6').each(function(element) {
if(re.test($(element.parentNode).className)) {
var new_span = new Element('span').update(element.textContent);
new_span.addClassName('theorem_label');
var next_el = element.next().firstChild;
next_el.parentNode.insertBefore(new_span, next_el);
var period = new Element('span').update('. ');
next_el.parentNode.insertBefore(period, next_el);
element.remove();
}
});
// add tombstone to proof, since gecko doesn't support :last-child properly
$$('div.proof').each(function(element) {
var l = element.childElements().length -1;
var span = new Element('span').update('\u00a0\u00a0\u25ae');
element.childElements()[l].insert(span);
})
}
function startup() { function startup() {
defaultCheck(); defaultCheck();
createControls(); // hallvord createControls(); // hallvord
@ -819,6 +842,7 @@ function startup() {
fixLinks(); fixLinks();
externalLinks(); externalLinks();
fontScale(); fontScale();
fixRunIn();
if (!isOp) notOperaFix(); if (!isOp) notOperaFix();
slideJump(); slideJump();
if (defaultView == 'outline') { if (defaultView == 'outline') {

View file

@ -392,3 +392,23 @@ span.keyboard {
margin:auto; margin:auto;
text-align:center; text-align:center;
} }
body {counter-reset: theorem lemma proposition corollary example remark}
.un_theorem *, .num_theorem *,
.un_lemma *, .num_lemma *,
.un_prop *, .num_prop *,
.un_cor *, .num_cor * {font-style: italic}
span.theorem_label {font-style:normal; font-weight:bold;}
.num_theorem .theorem_label:after {
content: " " counter(theorem); counter-increment: theorem;}
.num_lemma .theorem_label:after {
content: " " counter(lemma); counter-increment: lemma;}
.num_prop .theorem_label:after {
content: " " counter(proposition); counter-increment: proposition;}
.num_cor .theorem_label:after {
content: " " counter(corollary); counter-increment: corollary;}
.num_example .theorem_label:after {
content: " " counter(example); counter-increment: example;}
.num_remark .theorem_label:after {
content: " " counter(remark); counter-increment: remark;}

View file

@ -726,6 +726,7 @@ class WikiControllerTest < Test::Unit::TestCase
\usepackage{amsmath} \usepackage{amsmath}
\usepackage{amsfonts} \usepackage{amsfonts}
\usepackage{amssymb} \usepackage{amssymb}
\usepackage{amsthm}
\usepackage{graphicx} \usepackage{graphicx}
\usepackage{color} \usepackage{color}
\usepackage{ucs} \usepackage{ucs}
@ -923,6 +924,27 @@ class WikiControllerTest < Test::Unit::TestCase
\newcommand{\statusline}[2]{#2} \newcommand{\statusline}[2]{#2}
\newcommand{\toggle}[2]{#1} \newcommand{\toggle}[2]{#1}
% Theorem Environments
\theoremstyle{plain}
\newtheorem{theorem}{Theorem}
\newtheorem{lemma}{Lemma}
\newtheorem{prop}{Proposition}
\newtheorem{cor}{Corollary}
\newtheorem*{utheorem}{Theorem}
\newtheorem*{ulemma}{Lemma}
\newtheorem*{uprop}{Proposition}
\newtheorem*{ucor}{Corollary}
\theoremstyle{definition}
\newtheorem{def}{Definition}
\newtheorem{example}{Example}
\newtheorem*{udef}{Definition}
\newtheorem*{uexample}{Example}
\theoremstyle{remark}
\newtheorem{remark}{Remark}
\newtheorem{note}{Note}
\newtheorem*{uremark}{Remark}
\newtheorem*{unote}{Note}
%------------------------------------------------------------------- %-------------------------------------------------------------------
\begin{document} \begin{document}

View file

@ -65,15 +65,11 @@ class PageRendererTest < Test::Unit::TestCase
%{<mi>sin</mi><mo stretchy='false'>(</mo><mi>x</mi><mo stretchy='false'>)</mo></math></p>}, %{<mi>sin</mi><mo stretchy='false'>(</mo><mi>x</mi><mo stretchy='false'>)</mo></math></p>},
"equation $\\sin(x)$") "equation $\\sin(x)$")
assert_markup_parsed_as( re = Regexp.new('<h1 id=\'my_headline_\\d{1,4}\'>My Headline</h1>\n\n<p>that <span class=\'newWikiWord\'>Smart Engine GUI<a href=\'../show/SmartEngineGUI\'>\?</a></span></p>')
%{<h1 id='my_headline'>My Headline</h1>\n\n<p>that <span class='newWikiWord'>} +
%{Smart Engine GUI<a href='../show/SmartEngineGUI'>?</a></span></p>},
"My Headline\n===========\n\nthat SmartEngineGUI")
assert_markup_parsed_as( assert_match_markup_parsed_as(re, "My Headline\n===========\n\nthat SmartEngineGUI")
%{<h1 id='my_headline'>My Headline</h1>\n\n<p>that <span class='newWikiWord'>} +
%{Smart Engine GUI<a href='../show/SmartEngineGUI'>?</a></span></p>}, assert_match_markup_parsed_as(re, "#My Headline#\n\nthat SmartEngineGUI")
"#My Headline#\n\nthat SmartEngineGUI")
assert_markup_parsed_as( assert_markup_parsed_as(
%{<p>SVG <animateColor title='MathML'><span class='newWikiWord'>} + %{<p>SVG <animateColor title='MathML'><span class='newWikiWord'>} +
@ -159,13 +155,13 @@ class PageRendererTest < Test::Unit::TestCase
].join("\n") ].join("\n")
set_web_property :markup, :markdown set_web_property :markup, :markdown
assert_markup_parsed_as( re = Regexp.new(
"<h1 id='markdown_heading'>Markdown heading</h1>\n\n" + '<h1 id=\'markdown_heading_\d{1,4}\'>Markdown heading</h1>\n\n' +
"<p>h2. Textile heading</p>\n\n" + "<p>h2. Textile heading</p>\n\n" +
"<p><em>some</em> <strong>text</strong> <em>with</em> -styles-</p>\n\n" + "<p><em>some</em> <strong>text</strong> <em>with</em> -styles-</p>\n\n" +
"<ul>\n<li>list 1</li>\n\n<li>list 2</li>\n</ul>", "<ul>\n<li>list 1</li>\n\n<li>list 2</li>\n</ul>")
textile_and_markdown)
assert_match_markup_parsed_as(re, textile_and_markdown)
set_web_property :markup, :textile set_web_property :markup, :textile
assert_markup_parsed_as( assert_markup_parsed_as(
"<p>Markdown heading<br/>================</p>\n\n\n\t<h2>Textile heading</h2>" + "<p>Markdown heading<br/>================</p>\n\n\n\t<h2>Textile heading</h2>" +
@ -526,6 +522,11 @@ class PageRendererTest < Test::Unit::TestCase
assert_equal expected_output, test_renderer(revision).display_content, 'Rendering output not as expected' assert_equal expected_output, test_renderer(revision).display_content, 'Rendering output not as expected'
end end
def assert_match_markup_parsed_as(expected_output, input)
revision = Revision.new(:page => @page, :content => input, :author => Author.new('AnAuthor'))
assert_match expected_output, test_renderer(revision).display_content, 'Rendering output not as expected'
end
def rendered_content(page) def rendered_content(page)
test_renderer(page.revisions.last).display_content test_renderer(page.revisions.last).display_content
end end

View file

@ -518,6 +518,33 @@ Otherwise, a standard `verbatim` environment is used.
end end
def to_latex_div
type = self.attributes[:class]
id = self.attributes[:id]
case type
when /^un_(\w*)/
s = "\\begin{u#{$1}}"
# s += "[#{@children[0].send('children_to_latex')}]"
@children.delete_at(0)
s += "\n" + children_to_latex
s += "\\end{u#{$1}}\n"
when /^num_(\w*)/
s = "\\begin{#{$1}}"
# s += "[#{@children[0].send('children_to_latex')}]"
@children.delete_at(0)
s += "\n\\label{#{id}}\\hypertarget{#{id}}{}\n"
s += children_to_latex
s += "\\end{#{$1}}\n"
when /^proof/
s = "\\begin{proof}"
@children.delete_at(0)
s += "\n" + children_to_latex
s += "\\end{proof}\n"
else
s = children_to_latex
end
s
end
# Convert each child to html # Convert each child to html
def children_to_latex def children_to_latex

View file

@ -46,7 +46,7 @@ class MDElement
title = "id#{$uid}" title = "id#{$uid}"
end end
title title << "_" + rand(10000).to_s
end end
end end