Skip to content
Browse files

software work, version with html5+mathml

  • Loading branch information...
1 parent 68ce40d commit 6834dd93fe0500144b185244d49779327edc7d65 Ben Crowell committed May 15, 2010
Showing with 206 additions and 34 deletions.
  1. +1 −0 Makefile
  2. +8 −8 ch05/ch05.rbtex
  3. +184 −23 eruby_util.rb
  4. +1 −0 fruby
  5. +2 −0 scripts/harvest_aux_files.rb
  6. +8 −1 scripts/run_eruby.pl
  7. +2 −2 scripts/translate_to_html.rb
View
1 Makefile
@@ -32,6 +32,7 @@ book:
web:
WOPT='$(WOPT) --modern' $(RUN_ERUBY) w #... xhtml
+ WOPT='$(WOPT) --html5' $(RUN_ERUBY) w #... html 5
$(RUN_ERUBY) w #... html
# To set options, do, e.g., "WOPT='--no_write' make web". Options are documented in translate_to_html.rb.
View
16 ch05/ch05.rbtex
@@ -1101,6 +1101,14 @@ scalar-in-a-box idea leads to a contradiction, it wasn't a coincidence that we c
produced such an effect; a theory that lacks self-consistency doesn't have any models.
Self-check: Explain why parallel transporting a vector can only rotate it, not change its magnitude.
+<% marg(0) %>
+<%
+ fig(
+ 'torsion-story',
+ %q{Measuring $\partial^2 T/\partial x\partial y$ for a scalar $T$.}
+ )
+%>
+<% end_marg %>
There is, however, a different way in which scalars could behave counterintuitively, and this one is mathematically
self-consistent. Suppose that Helen lives in two spatial dimensions and owns a thermometer. She wants to measure
@@ -1114,14 +1122,6 @@ afternoon temperature sample $\Delta T_2$ would be at the same point in space C
the landscape, so the sample points C and E are different, but this just confirms what she already knew: the space isn't
flat.\footnote{This point was mentioned on page \pageref{riemann-curvature-tensor}, in connection with the
definition of the Riemann tensor.}
-<% marg(80) %>
-<%
- fig(
- 'torsion-story',
- %q{Measuring $\partial^2 T/\partial x\partial y$ for a scalar $T$.}
- )
-%>
-<% end_marg %>
None of this seems surprising yet, but there are now two qualitatively different ways that her analysis of her data
could turn out, indicating qualitatively different things about the laws of physics in her universe.
View
207 eruby_util.rb
@@ -1,5 +1,11 @@
-# This is a cut-down version of the one used for LM and SN.
+# See INTERNALS for documentation on all the files: geom.pos, marg.pos, chNN.pos,
+# figfeedbackNN, all.pos.
+$n_code_listing = 0
+$hw_number = 0
+$hw = []
+$hw_has_solution = []
+$hw_names_referred_to = []
$tex_points_to_mm = (25.4)/(65536.*72.27)
$n_marg = 0
$in_marg = false
@@ -28,10 +34,51 @@
$count_section_commands = 0
$section_level = -1
-$hw_number = 0
-$hw = []
-$hw_has_solution = []
-$hw_names_referred_to = []
+
+#--------------------------------------------------------------------------
+# The following code is a workaround for a bug in latex. The symptom is that I get
+# "Missing \endcsname inserted" in a few isolated cases where I use a pageref inside
+# the caption of a figure. See meki latex notes for more details. In these cases, I
+# can get the refs using eruby instead of latex. See pageref_workaround() and ref_workaround() below.
+
+#qwe
+# Code similar to this is duplicated in translate_to_html.rb:
+refs_file = 'save.ref'
+$ref = {}
+if File.exist?(refs_file) then # It's not an error if the file doesn't exist yet; references are just not defined yet, and that's normal for the first time on a fresh file.
+ File.open(refs_file,'r') do |f|
+ # lines look like this:
+ # fig:entropygraphb,h,255
+ t = f.gets(nil) # nil means read whole file
+ t.scan(/(.*),(.*),(.*)/) { |label,number,page|
+ $ref[label] = [number,page.to_i]
+ }
+ end
+end
+
+def ref_workaround(label)
+ return $ref[label][0]
+end
+
+def pageref_workaround(label)
+ return $ref[label][1].to_s
+end
+
+#--------------------------------------------------------------------------
+
+# set by run_eruby.pl
+# tells whether the book is calculus-based
+# if set, ignore markers on hw and section in L&M for optional calc-based material
+def calc
+ return ENV['CALC']=='1'
+end
+
+# set by run_eruby.pl
+# for use when generating screen-resolution figures
+# e.g., ../9share/optics
+def shared_figs
+ return [ENV['SHARED_FIGS'],ENV['SHARED_FIGS2']]
+end
def is_print
return ENV['BOOK_OUTPUT_FORMAT']!='web'
@@ -184,15 +231,14 @@ def pos_file_exists
return $pos_exists
end
-# looks at global variable $n_marg to see which margin-group we're working on
# returns height in mm, or nil if the all.pos file doesn't exist yet, or figure not listed in it
def height_of_marg
#debug = ($ch.to_i==4 and $n_marg==6)
debug = false
if !(File.exist?($marg_file)) then return nil end
if !pos_file_exists() then return nil end
# First, figure out what figures are associated with the current margin block.
- mine = Hash.new # keys are, e.g., "fig:atomic-clock-boarding-plane"
+ mine = Hash.new
File.open($marg_file,'r') do |f|
# The file grows by appending with each iteration. If the user isn't modifying the tex file (drastically) between
# runs, then it should all just be exact repetition. If not, then we just use the freshest available data. At any given
@@ -259,6 +305,8 @@ def get_low_and_hi!(found,lo_y,hi_y,filename,mine)
def figure_exists_in_my_own_dir?(name)
ch = $ch
+ if $ch=='001' then ch='00' end
+ if $ch=='002' then ch='00' end
return (File.exist?("ch#{ch}/figs/#{name}.pdf") or File.exist?("ch#{ch}/figs/#{name}.jpg") or File.exist?("ch#{ch}/figs/#{name}.png"))
end
@@ -320,6 +368,14 @@ def fig(name,caption=nil,options={})
options['anonymous']=(!caption)
end
dir = "\\figprefix\\chapdir/figs"
+ if !figure_exists_in_my_own_dir?(name) then
+ # bug: doesn't support \figprefix
+ s = shared_figs()
+ dir = s[0]
+ unless (File.exist?("#{dir}/#{name}.pdf") or File.exist?("#{dir}/#{name}.jpg") or File.exist?("#{dir}/#{name}.png")) then
+ dir = s[1]
+ end
+ end
#------------------------------------------------------------
if is_print then fig_print(name,caption,options,dir) end
#------------------------------------------------------------
@@ -487,6 +543,31 @@ def die(name,message)
exit(-1)
end
+def begin_hw(name,difficulty=1,options={})
+ if difficulty==nil then difficulty=1 end # why doesn't this happen by default?
+ if calc() then options['calc']=false end
+ calc = ''
+ if options['calc'] then calc='1' end
+ print "\\begin{homework}{#{name}}{#{difficulty}}{#{calc}}"
+ $hw_number += 1
+ $hw[$hw_number] = name
+ $hw_has_solution[$hw_number] = false
+end
+
+def hw_solution()
+ $hw_has_solution[$hw_number] = true
+ print "\\hwsoln"
+end
+
+def hw_ref(name)
+ print "\\ref{hw:#{name}}"
+ $hw_names_referred_to.push(name)
+end
+
+def end_hw()
+ print "\\end{homework}"
+end
+
def end_sec()
$count_section_commands += 1
$section_level -= 1
@@ -497,7 +578,7 @@ def begin_sec(title,pagebreak=nil,label='',options={})
$section_level += 1
# In LM, section level 1=section, 2=subsection, 3=subsubsection; 0 would be chapter, but chapters aren't done with begin_sec()
if $section_level==0 then
- $stderr.print "warning, at #{$count_section_commands}th begin/end section command, ch #{$ch}, section #{title}, section level=#{$section_level}, zero section level (happens in NP Preface)\n"
+ $stderr.print "warning, at #{$count_section_commands}th section command, ch #{$ch}, section #{title}, section level=#{$section_level}, zero section level (happens in NP Preface)\n"
$section_level = 1
end
if pagebreak==nil then pagebreak=4-$section_level end
@@ -507,9 +588,13 @@ def begin_sec(title,pagebreak=nil,label='',options={})
if $section_level>=3 then pagebreak = '' end
macro = ''
label_level = ''
+ if calc() then options['calc']=false end
if $section_level==1 then
+ if options['calc'] and options['optional'] then macro='myoptionalcalcsection' end
+ if options['calc'] and !options['optional'] then macro='mycalcsection' end
+ if !options['calc'] and options['optional'] then macro='myoptionalsection' end
+ if !options['calc'] and !options['optional'] then macro='mysection' end
label_level = 'sec'
- macro = 'mysection'
end
if $section_level==2 then
if options['toc']==false then
@@ -523,15 +608,85 @@ def begin_sec(title,pagebreak=nil,label='',options={})
macro = 'subsubsection'
label_level = 'subsubsec'
end
+ #$stderr.print "level=#{$section_level}, title=#{title}\n"
+ # In LM, sections are supposed to be titlecase.
+ # May be a section in LM, but a subsection in SN, and that's why we may need to change to and from titlecase automatically, and it's not an error
+ # that should be reported to the user.
+ if $section_level>=2 then
+ title = remove_titlecase(title)
+ else
+ title = add_titlecase(title)
+ end
if label != '' then label="\\label{#{label_level}:#{label}}" end
print "\\#{macro}#{pagebreak}{#{title}}#{label}\n"
end
+def add_titlecase(title)
+ foo = title.clone
+ # Examples:
+ # Current-conducting -> Current-Conducting
+ foo.gsub!(/(?<![\w'"`{}\\])(\w)/) {$1.upcase} # Change every initial letter to uppercase. Handle Bob's, Schr\"odinger, Amp\`{e}re's
+ [ 'a','the','and','or','if','for','of','on','by' ].each { |tiny| # Change specific short words back to lowercase.
+ foo.gsub!(/(?<!\w)#{tiny}(?!\w)/i) {tiny}
+ }
+ foo = initial_cap(foo) # Make sure initial word ends up capitalized.
+ acronyms_and_symbols_uppercase(foo) # E.g., FWHM.
+ #if title != foo then $stderr.print "changing title from #{title} to #{foo}\n" end
+ return foo
+end
+
+def remove_titlecase(title)
+ foo = title.clone
+ foo = initial_cap(foo.downcase) # first letter is capital, everything after that lowercase
+ # restore caps on proper nouns:
+ [ 'Cartesian','Kepler','Big Bang','Gauss','Amp\\`{e}re','Maxwell','Faraday',
+ 'Huygens','Schr\\"odinger','Schr\\\"odinger','Greek','Biot','Savart','Doppler','Lorentz','Michelson','Morley' ].each { |proper|
+ foo.gsub!(/(?<!\w)#{proper}/i) {|x| initial_cap(x)}
+ # ... the negative lookbehind prevents, e.g., damped and example from becoming DAmped and ExAmple
+ # If I had a word like "amplification" in a title, I'd need to special-case that below and change it back.
+ }
+ acronyms_and_symbols_uppercase(foo) # e.g., FWHM
+ return foo
+end
+
+def acronyms_and_symbols_uppercase(foo)
+ # Acronyms and symbols that need to be uppercase no matter what:
+ foo.gsub!(/(?<!\w)(q|fwhm)(?!\w)/) {$1.upcase}
+end
+
+def initial_cap(x)
+ # Note that we have some subsections like "2. The medium is not transported with the wave.", where the initial cap is not the first character.
+ # These are handled correctly because it's sub(), not gsub(), so it just changes the first a-zA-Z character.
+ # The A-Z case is the one where it's already got an initial cap (e.g., don't want to end up with "HEllo".
+ return x.sub(/([a-zA-Z])/) {|x| x.upcase}
+end
+
def end_chapter
$section_level -= 1
if $section_level != -1 then
- $stderr.print "warning, at end_chapter, ch #{$ch}, section level at end of chapter is #{$section_level}, should be -1; probably begin_sec's and end_sec's are not properly balanced (happens in NP preface)\n"
+ $stderr.print "warning, at end_chapter, ch #{$ch}, section level at end of chapter is #{$section_level}, should be -1; probably begin_sec's and end_sec's are not properly balanced (happens in NP preface)\n"
end
+ $hw_names_referred_to.each { |name|
+ $stderr.print "hwref:#{name}\n"
+ }
+ File.open("ch#{$ch}_problems.csv",'w') { |f|
+ # book,ch,num,name
+ book = ENV['BK']
+ chnum = $ch.to_i
+ if $ch=='002' then chnum=0 end
+ 1.upto($hw_number) { |i|
+ name = $hw[i]
+ f.print "#{book},#{chnum},#{i},#{name},#{$hw_has_solution[i]?'1':'0'}\n"
+ }
+ }
+end
+
+def code_listing(filename,code)
+ print code
+ $n_code_listing = $n_code_listing+1
+ File.open("code_listing_ch#{$ch}_#{$n_code_listing}_#{filename}",'w') { |f|
+ f.print code
+ }
end
def chapter(number,title,label,caption='',options={})
@@ -554,11 +709,29 @@ def chapter(number,title,label,caption='',options={})
}
opener = options['opener']
if opener!='' then
+ if !figure_exists_in_my_own_dir?(opener) then
+ # bug: doesn't support \figprefix
+ # ! LaTeX Error: File `ch02/figs/../9share/mechanics/figs/pool' not found.
+ s = shared_figs()
+ dir = s[0]
+ unless (File.exist?("#{dir}/#{opener}.pdf") or File.exist?("#{dir}/#{opener}.jpg") or File.exist?("#{dir}/#{opener}.png")) then
+ dir = s[1]
+ end
+ options['opener']="../../#{dir}/#{opener}"
+ end
if options['anonymous']=='default' then
options['anonymous']=(caption=='')
end
end
- chapter_print(number,title,label,caption,options)
+ if is_print then chapter_print(number,title,label,caption,options) end
+ if is_web then chapter_web(number,title,label,caption,options) end
+end
+
+def chapter_web(number,title,label,caption,options)
+ if options['opener']!='' then
+ process_fig_web(options['opener'],caption,options)
+ end
+ print "\\mychapter{#{title}}\n"
end
def chapter_print(number,title,label,caption,options)
@@ -609,15 +782,3 @@ def chapter_print(number,title,label,caption,options)
end
print "#{result}\\label{#{label}}\n"
end
-
-def begin_hw(name,difficulty=1,options={})
- if difficulty==nil then difficulty=1 end # why doesn't this happen by default?
- print "\\begin{homework}{#{name}}{#{difficulty}}{}"
- $hw_number += 1
- $hw[$hw_number] = name
- $hw_has_solution[$hw_number] = false
-end
-
-def end_hw()
- print "\\end{homework}"
-end
View
1 fruby
@@ -16,6 +16,7 @@
# <% 3.times do %> rah <% end %>
# <% if foo %> foo <% end %>
# Every block has to be a syntactically self-contained piece of ruby code.
+# Variables assigned to in one piece of code *are* available in later pieces of code.
# This type of thing has to be accomplished by using a single block of ruby code,
# with print statements inside it.
# Bugs:
View
2 scripts/harvest_aux_files.rb
@@ -3,6 +3,8 @@
# The purpose of this script is to save the information in the aux files so we don't have
# to run pdftex three times every time we want to make html output. It collects all the
# aux files, parses them, and saves them in save.ref .
+# I also use this in eruby_util.rb for a workaround for a bug in latex that sometimes
+# makes it impossible to use a pageref ("Missing \endcsname inserted").
files = Dir["ch*/*.aux"]
View
9 scripts/run_eruby.pl
@@ -32,6 +32,8 @@
if ($wopt=~/\-\-wiki/) {$wiki=1}
my $xhtml = 0;
if ($wopt=~/\-\-modern/) {$xhtml=1}
+my $html5 = 0;
+if ($wopt=~/\-\-html5/) {$html5=1}
print "run_eruby.pl, no_write=$no_write, wiki=$wiki, xhtml=$xhtml\n";
@@ -99,7 +101,12 @@
$html = $html . '.wiki';
}
else {
- $html = $html . '.html';
+ if ($html5) {
+ $html = $html . '.html5';
+ }
+ else {
+ $html = $html . '.html';
+ }
}
}
if ($no_write) {$html = '/dev/null'}
View
4 scripts/translate_to_html.rb
@@ -270,7 +270,7 @@ def fatal_error(message)
# In the following, the main point of the icon is to allow me to tell, for testing purposes, whether I'm seeing the xhtml version
# or the html version. I'm not displaying any icon for the html version, since that would just clutter up the page.
-if $modern then
+if $modern and !$html5 then
valid_icon = '<p><img src="http://www.w3.org/Icons/valid-xhtml11-blue.png" alt="Valid XHTML 1.1 Strict" height="31" width="88"/></p>'
else
#valid_icon = '<p><img src="http://www.w3.org/Icons/valid-html401-blue" alt="Valid HTML 4.01 Strict" height="31" width="88"/></p>'
@@ -1514,7 +1514,7 @@ def newlines_to_spaces(s)
-
+# Code similar to this is duplicated in eruby_util.rb.
refs_file = 'save.ref'
unless File.exist?(refs_file) then
$stderr.print "File #{refs_file} doesn't exist. Do a 'make book' to create it."

0 comments on commit 6834dd9

Please sign in to comment.
Something went wrong with that request. Please try again.