diff options
Diffstat (limited to 'doc/talks')
-rw-r--r-- | doc/talks/go_talk-20091030.pdf | bin | 247502 -> 0 bytes | |||
-rw-r--r-- | doc/talks/go_talk-20100112.html | 411 | ||||
-rw-r--r-- | doc/talks/go_talk-20100121.html | 453 | ||||
-rw-r--r-- | doc/talks/go_talk-20100323.html | 395 | ||||
-rw-r--r-- | doc/talks/gofrontend-gcc-summit-2010.pdf | bin | 125185 -> 0 bytes | |||
-rw-r--r-- | doc/talks/io2010/balance.go | 168 | ||||
-rw-r--r-- | doc/talks/io2010/decrypt.go | 85 | ||||
-rw-r--r-- | doc/talks/io2010/encrypt.go | 52 | ||||
-rw-r--r-- | doc/talks/io2010/eval1.go | 227 | ||||
-rw-r--r-- | doc/talks/io2010/eval2.go | 259 | ||||
-rw-r--r-- | doc/talks/io2010/talk.pdf | bin | 1094941 -> 0 bytes | |||
-rw-r--r-- | doc/talks/io2011/Real_World_Go.pdf | bin | 609477 -> 0 bytes | |||
-rw-r--r-- | doc/talks/io2011/Writing_Web_Apps_in_Go.pdf | bin | 729499 -> 0 bytes | |||
-rw-r--r-- | doc/talks/java-typing.png | bin | 19328 -> 0 bytes | |||
-rw-r--r-- | doc/talks/slidy.css | 277 | ||||
-rw-r--r-- | doc/talks/slidy.js | 2772 |
16 files changed, 0 insertions, 5099 deletions
diff --git a/doc/talks/go_talk-20091030.pdf b/doc/talks/go_talk-20091030.pdf Binary files differdeleted file mode 100644 index 5139ff2bd..000000000 --- a/doc/talks/go_talk-20091030.pdf +++ /dev/null diff --git a/doc/talks/go_talk-20100112.html b/doc/talks/go_talk-20100112.html deleted file mode 100644 index 2e3643512..000000000 --- a/doc/talks/go_talk-20100112.html +++ /dev/null @@ -1,411 +0,0 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" - "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> -<head> -<title>Go (January 12, 2010)</title> -<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> -<meta name="font-size-adjustment" content="-1" /> -<link rel="stylesheet" href="slidy.css" - type="text/css" media="screen, projection, print" /> -<script src="slidy.js" type="text/javascript"> -</script> -</head> -<body> -<!-- this defines the slide background --> - -<div class="background"> - - <div class="header"> - <!-- sized and colored via CSS --> - </div> - - <div class="footer"></div> - </div> - -<div class="slide titlepage"> -<div style="height: 135px; width: 480px; overflow: hidden; position: fixed; top: auto; bottom: 10px; left: auto; right: 0; "> -<img src="../gordon/bumper480x270.png" style="margin: -135px 0 0 0;"/> -</div> -<!-- <img src="google.png" style="position: fixed; top: auto; bottom: 30px; left: 20px; right: auto;"/> --> -<br/> -<img src="../go-logo-white.png"> -<br/> -<br/> -<h1 style="padding-right: 0pt; margin-right: 0pt; color: #0066cc; font-size: 250%; border-bottom: 0px;">The Go Programming Language</h1> -<div style="color: #ffcc00;"> -<h2>Russ Cox</h2> -<!-- <h3><i>rsc@google.com</i></h3> --> -<br/> -<h3>Stanford University<br/><br/>January 12, 2010</h3> -</div> -</div> - -<div class="slide"> - <h1>Go</h1> - - <h2>New</h2> - <h2>Experimental</h2> - <h2>Concurrent</h2> - <h2>Garbage-collected</h2> - <h2>Systems</h2> - <h2>Language</h2> -</div> - -<div class="slide"> - <h1>Hello, world</h1> -<pre> -package main - -import "fmt" - -func main() { - fmt.Printf("Hello, 世界\n") -} -</pre> -</div> - -<div class="slide"> - <h1>History</h1> - - <h2>Design started in late 2007.</h2> - <h2>Implementation starting to work mid-2008.</h2> - <h2>Released as an open source project in November 2009.</h2> - <h2>Work continues.<h2> - <h2>Robert Griesemer, Ken Thompson, Rob Pike, Ian Lance Taylor, Russ Cox, many others</h2> -</div> - -<div class="slide"> - <h1>Why?</h1> - - <h2>Go fast!</h2> - <h2>Make programming fun again.</h2> -</div> - -<div class="slide"> - <h1>Why isn't programming fun?</h1> - - <div class="incremental"> - <h2>Compiled, statically-typed languages (C, C++, Java) require too much typing and too much typing:</h2> - - <ul> - <li>verbose, lots of repetition</li> - <li>too much focus on type hierarchy</li> - <li>types get in the way as much as they help</li> - <li>compiles take far too long</li> - </ul> - </div> - - <div class="incremental"> - <h2>Dynamic languages (Python, JavaScript) fix these problems (no more types, no more compiler) but introduce others:</h2> - - <ul> - <li>errors at run time that should be caught statically</li> - <li>no compilation means slow code</li> - </ul> - </div> - - <h2 class="incremental">Can we combine the best of both?</h2> -</div> - -<div class="slide"> - <h1>Go</h1> - - <h2>Make the language fast.</h2> - <h2>Make the tools fast.</h2> -</div> - -<div class="slide"> - <h1>Go Approach: Static Types</h1> - - <h2>Static types, but declarations can infer type from expression:</h2> - -<pre> -var one, hi = 1, "hello" - -var double = func(x int) int { return x*2 } -</pre> - - <h2>Not full Hindley-Milner type inference.</h2> -</div> - - -<div class="slide"> - <h1>Go Approach: Methods</h1> - - <h2>Methods can be defined on any type.</h2> - -<pre> -type Point struct { - X, Y float64 -} - -func (p Point) Abs() float64 { - return math.Sqrt(p.X*p.X + p.Y*p.Y) -} -</pre> -</div> - -<div class="slide"> - <h1>Go Approach: Methods</h1> - - <h2>Methods can be defined on any type.</h2> - -<pre> -type MyFloat float64 - -func (f MyFloat) Abs() float64 { - v := float64(f) - if v < 0 { - v = -v - } - return v -} -</pre> -</div> - -<div class="slide"> - <h1>Go Approach: Abstract Types</h1> - - <h2>An interface type lists a set of methods. Any value with those methods satisfies the interface.</h2> - -<pre> -type Abser interface { - Abs() float64 -} - -func AbsPrinter(a Abser) -</pre> - - <h2>Can use Point or MyFloat (or ...):</h2> - -<pre> -p := Point{3, 4} -AbsPrinter(p) - -f := MyFloat(-10) -AbsPrinter(f) -</pre> - - <h2>Notice that Point never declared that it implements Abser. It just does. Same with MyFloat.</h2> -</div> - -<div class="slide"> - <h1>Go Approach: Packages</h1> - - <h2>A Go program comprises one or more packages.</h2> - <h2>Each package is one or more source files compiled and imported as a unit.</h2> -<pre> -package draw - -type Point struct { - X, Y int -} -</pre> - -<pre> -package main - -import "draw" - -var p draw.Point -</pre> -</div> - -<div class="slide"> - <h1>Go Approach: Visibility</h1> - - <h2>Inside a package, all locally defined names are visible in all source files.</h2> - - <h2>When imported, only the upper case names are visible.</h2> - -<pre> -package draw - -type <span style="color: black;">Point</span> struct { - <span style="color: black;">X</span>, <span style="color: black;">Y</span> int - dist float64 -} - -type cache map[Point] float64 -</pre> - -<h2>Clients that <code>import "draw"</code> can use the black names only.</h2> - -<h2>“Shift is the new <code>public</code>.”</h2> -</div> - -<div class="slide"> - <h1>Go Approach: Concurrency</h1> - - <h2>Cheap to create a new flow of control (goroutine):</h2> - -<pre> -func main() { - go expensiveComputation(x, y, z) - anotherExpensiveComputation(a, b, c) -} -</pre> - - <h2>Two expensive computations in parallel.</h2> -</div> - -<div class="slide"> - <h1>Go Approach: Synchronization</h1> - - <h2>Use explicit messages to communicate and synchronize.</h2> - -<pre> -func computeAndSend(ch chan int, x, y, z int) { - ch <- expensiveComputation(x, y, z) -} - -func main() { - ch := make(chan int) - go computeAndSend(ch, x, y, z) - v2 := anotherExpensiveComputation(a, b, c) - v1 := <-ch - fmt.Println(v1, v2) -} -</pre> - <h2>Notice communication of result in addition to synchronization.</h2> -</div> - -<div class="slide"> - <h1>Go Fast: Language</h1> - - <h2 class="incremental">Static types: enough to compile well, but inferred much of the time.</h2> - - <h2 class="incremental">Methods: on any type, orthogonal to type system.</h2> - - <h2 class="incremental">Abstract types: interface values, relations inferred statically.</h2> - - <h2 class="incremental">Visibility: inferred from case of name.</h2> - - <h2 class="incremental">Concurrency: lightweight way to start new thread of control.</h2> - - <h2 class="incremental">Synchronization: explicit, easy message passing.</h2> - - <br/> - - <h2 class="incremental">Lightweight feel of a scripting language but compiled.</h2> -</div> - -<div class="slide"> - <h1>Compile fast</h1> - - <div class="incremental"> - <h2>Observation: much of the compile time for a source file is spent processing - other, often unrelated files.</h2> - - <h2>In C: <code>a.c</code> includes <code>b.h</code>, which includes <code>c.h</code>, which includes <code>d.h</code>. - </h2> - - <h2>Except that it's more often a tree instead of a chain.</h2> - - <h2>On my Mac (OS X 10.5.8, gcc 4.0.1):</h2> - <ul> - <li>C: <code>#include <stdio.h></code> reads 360 lines from 9 files. - <li>C++: <code>#include <iostream></code> reads 25,326 lines from 131 files. - <li>Objective C: <code>#include <Carbon/Carbon.h></code> reads 124,730 lines from 689 files. - </ul> - - <h2>And we haven't done any real work yet!</h2> - - <h2>Same story in Java, Python, but reading binaries instead of source files.</h2> - </div> -</div> - -<div class="slide"> - <h1>Implementation: Summarize Dependencies</h1> - -<pre> -package gui - -import "draw" - -type Mouse struct { - Loc draw.Point - Buttons uint -} -</pre> - <h2>Compiled form of <code>gui</code> summarizes the necessary part of <code>draw</code> (just <code>Point</code>).</h2> - -</div> - -<div class="slide"> - <h1>Implementation: Summarize Dependencies</h1> - - <h2>Compiled form of <code>gui</code> summarizes the necessary part of <code>draw</code> (just <code>Point</code>). Pseudo-object:</h2> - -<pre> -package gui -type draw.Point struct { - X, Y int -} -type gui.Mouse struct { - Loc draw.Point - Buttons uint -} -</pre> - - <h2>A file that imports <code>gui</code> compiles without consulting <code>draw</code> or its dependencies.</h2> - - <h2>In Go: <code>import "fmt"</code> reads <i>one</i> file: 184 lines summarizing types from 7 packages.</h2> - - <h2>Tiny effect in this program but can be exponential in large programs.</h2> -</div> - -<div class="slide"> - <h1>Compilation Demo</h1> - - <h2>Build all standard Go packages: ~120,000 lines of code.</h2> -</div> - -<div class="slide"> - <h1>Go Status</h1> - - <div class="incremental"> - <div> - <h2>Open source:</h2> - <ul> - <li>released on November 10, 2009 - <li>regular releases (~ weekly) - <li>all development done in public Mercurial repository - <li>outside contributions welcome - </ul> - </div> - - <div> - <h2>Portable:</h2> - <ul> - <li>FreeBSD, Linux, OS X (x86, x86-64) - <li>(in progress) Linux arm, Native Client x86, Windows x86. - </ul> - </div> - - <div> - <h2>Still in progress, experimental. Yet to come:</h2> - <ul> - <li>mature garbage collector - <li>generics? - <li>exceptions? - <li>unions or sum types? - </ul> - </div> - </div> - -</div> - -<div class="slide titlepage"> - <h1>Questions?</h1> - <br><br> - <center> - <img src="../gordon/bumper640x360.png"> - </center> - <br><br> - <div style="color: #ffcc00;"> - <!-- <h3><i>rsc@google.com</i></h3> --> - </div> -</div> - -</body></html> diff --git a/doc/talks/go_talk-20100121.html b/doc/talks/go_talk-20100121.html deleted file mode 100644 index d5e4bc66f..000000000 --- a/doc/talks/go_talk-20100121.html +++ /dev/null @@ -1,453 +0,0 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" - "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> -<head> -<title>Go, Networked (January 21, 2010)</title> -<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> -<meta name="font-size-adjustment" content="-1" /> -<link rel="stylesheet" href="slidy.css" - type="text/css" media="screen, projection, print" /> -<script src="slidy.js" type="text/javascript"> -</script> -</head> -<body> -<!-- this defines the slide background --> - -<div class="background"> - - <div class="header"> - <!-- sized and colored via CSS --> - </div> - - <div class="footer"></div> - </div> - -<div class="slide titlepage"> -<div style="height: 135px; width: 480px; overflow: hidden; position: fixed; top: auto; bottom: 10px; left: auto; right: 0; "> -<img src="../gordon/bumper480x270.png" style="margin: -135px 0 0 0;"/> -</div> -<!-- <img src="../google.png" style="position: fixed; top: auto; bottom: 30px; left: 20px; right: auto;"/> --> -<br/> -<img src="../go-logo-white.png"> -<br/> -<br/> -<h1 style="padding-right: 0pt; margin-right: 0pt; color: #0066cc; font-size: 250%; border-bottom: 0px;">The Go Programming Language</h1> -<div style="color: #ffcc00;"> -<h2>Russ Cox</h2> -<!-- <h3><i>rsc@google.com</i></h3> --> -<br/> -<h3>CNS Winter Research Review<br/><br/>January 21, 2010</h3> -<br/> -<br/> -<!-- -<h4><i>click to start; then left/right arrow to change slides</i></h4> --> -</div> -</div> - -<div class="slide"> - <h1>Go</h1> - - <h2>New</h2> - <h2>Experimental</h2> - <h2>Concurrent</h2> - <h2>Garbage-collected</h2> - <h2>Systems</h2> - <h2>Language</h2> -</div> - -<div class="slide"> - <h1>Hello, world</h1> -<pre> -package main - -import "fmt" - -func main() { - fmt.Printf("Hello, 世界\n") -} -</pre> -</div> - -<div class="slide"> - <h1>History</h1> - - <h2>Design started in late 2007.</h2> - <h2>Implementation starting to work mid-2008.</h2> - <h2>Released as an open source project in November 2009.</h2> - <h2>Work continues.<h2> - <h2>Robert Griesemer, Ken Thompson, Rob Pike, Ian Lance Taylor, Russ Cox, many others</h2> -</div> - -<div class="slide"> - <h1>Goals and Motivation</h1> - - <h2>Go fast!</h2> - <h2>Make programming fun again.</h2> - <h2>Targeted at systems software, broadly.</h2> -</div> - -<div class="slide"> - <h1>Why isn't programming fun?</h1> - - <div class="incremental"> - <h2>Compiled, statically-typed languages (C, C++, Java) require too much typing and too much typing:</h2> - - <ul> - <li>verbose, lots of repetition</li> - <li>too much focus on type hierarchy</li> - <li>types get in the way as much as they help</li> - <li>compiles take far too long</li> - </ul> - </div> - - <div class="incremental"> - <h2>Dynamic languages (Python, JavaScript) fix these problems (no more types, no more compiler) but introduce others:</h2> - - <ul> - <li>errors at run time that should be caught statically</li> - <li>no compilation means slow code</li> - </ul> - </div> - - <h2 class="incremental">Can we combine the best of both?</h2> -</div> - -<div class="slide"> - <h1>Why a new language?</h1> - - <div class="incremental"> - <h2>No new systems language in 10+ years.</h2> - <h2>Current languages designed before ...</h2> - <h3>... rise of large-scale, networked and multicore computing</h3> - <h3>... rise of Internet-scale distributed development (many libraries)</h3> - </div> -</div> - -<div class="slide"> - <h1>Go</h1> - - <h2>Make the language fast.</h2> - <h2>Make the tools fast.</h2> -</div> - -<div class="slide"> - <h1>Compilation Demo</h1> - - <h2>Build all standard Go packages: ~120,000 lines of code.</h2> -</div> - -<div class="slide"> - <h1>Go in one slide</h1> - - <h2 class="incremental">Lightweight syntax.</h2> - - <h2 class="incremental">Static types: enough to compile well, but inferred much of the time.</h2> - - <h2 class="incremental">Methods: on any type, orthogonal to type system.</h2> - - <h2 class="incremental">Abstract types: interface values, relations inferred statically.</h2> - - <h2 class="incremental">Visibility: inferred from case of name.</h2> - - <h2 class="incremental">First-class functions.</h2> - - <h2 class="incremental">Garbage collection.</h2> - - <br/> - - <h2 class="incremental">Lightweight feel of a scripting language but compiled.</h2> -</div> - -<div class="slide"> - <h1>Go, concurrently</h1> - - <h2>Cheap to create a new flow of control (goroutine):</h2> - -<pre> -func main() { - go expensiveComputation(x, y, z) - anotherExpensiveComputation(a, b, c) -} -</pre> - - <h2>Two expensive computations in parallel.</h2> -</div> - -<div class="slide"> - <h1>Go, concurrently</h1> - - <h2>Cheap to create a new flow of control (goroutine):</h2> - -<pre> - for { - rw := l.Accept() - conn := newConn(rw, handler) - go conn.serve() - } -</pre> - - <h2>Concurrent web server.</h2> - <h2>Network connections multiplexed onto epoll.</h2> - <ul> - <li>many blocked Read calls != many blocked OS threads</li> - </ul> - -</div> - -<div class="slide"> - <h1>Go, synchronized</h1> - - <h2>Use explicit messages to communicate and synchronize.</h2> - -<pre> -func computeAndSend(ch chan int, x, y, z int) { - ch <- expensiveComputation(x, y, z) -} - -func main() { - ch := make(chan int) - go computeAndSend(ch, x, y, z) - v2 := anotherExpensiveComputation(a, b, c) - v1 := <-ch - fmt.Println(v1, v2) -} -</pre> - <h2>Notice communication of result in addition to synchronization.</h2> -</div> - -<div class="slide"> - <h1>Go, synchronized</h1> - - <h2>RPC client</h2> - -<pre> -func (client *Client) Call(method string, args, reply interface{}) os.Error { - // Send RPC message. - call := client.Go(method, args, reply, nil) - - // Read reply from Done channel. - <-call.Done - - return call.Error -} -</pre> -</div> - -<div class="slide"> - <h1>Go, synchronized</h1> - - <h2>RPC client demux</h2> - -<pre> -func (client *Client) input() { - for { - resp := client.readResponse() - client.mutex.Lock() - c := client.pending[resp.Seq] - client.pending[resp.Seq] = c, false - client.mutex.Unlock() - if resp.Error != "" { - c.Error = os.ErrorString(resp.error) - } - resp.Decode(c.Reply) - c.Done <- c - } -} -</pre> -</div> - -<div class="slide"> - <h1>Go, synchronized</h1> - - <h2>RPC client demux</h2> - -<pre> -func (client *Client) input() { - for { - <font style="color: black;">resp := client.readResponse()</font> - client.mutex.Lock() - c := client.pending[resp.Seq] - client.pending[resp.Seq] = c, false - client.mutex.Unlock() - if resp.Error != "" { - c.Error = os.ErrorString(resp.error) - } - resp.Decode(c.Reply) - c.Done <- c - } -} -</pre> -<h2>Read response from network.</h2 -</div> - -<div class="slide"> - <h1>Go, synchronized</h1> - - <h2>RPC client demux</h2> - -<pre> -func (client *Client) input() { - for { - resp := client.readResponse() - <font style="color: black;">client.mutex.Lock() - c := client.pending[resp.Seq] - client.pending[resp.Seq] = c, false - client.mutex.Unlock()</font> - if resp.Error != "" { - c.Error = os.ErrorString(resp.error) - } - resp.Decode(c.Reply) - c.Done <- c - } -} -</pre> -<h2>Look up request by sequence number.</h2 -</div> - -<div class="slide"> - <h1>Go, synchronized</h1> - - <h2>RPC client demux</h2> - -<pre> -func (client *Client) input() { - for { - resp := client.readResponse() - client.mutex.Lock() - c := client.pending[resp.Seq] - client.pending[resp.Seq] = c, false - client.mutex.Unlock() - <font style="color: black;">if resp.Error != "" { - c.Error = os.ErrorString(resp.error) - } - resp.Decode(c.Reply)</font> - c.Done <- c - } -} -</pre> -<h2>Decode response fields from payload.</h2 -</div> - -<div class="slide"> - <h1>Go, synchronized</h1> - - <h2>RPC client demux</h2> - -<pre> -func (client *Client) input() { - for { - resp := client.readResponse() - client.mutex.Lock() - c := client.pending[resp.Seq] - client.pending[resp.Seq] = c, false - client.mutex.Unlock() - if resp.Error != "" { - c.Error = os.ErrorString(resp.error) - } - resp.Decode(c.Reply) - <font style="color: black;">c.Done <- c</font> - } -} -</pre> -<h2>Tell client that it finished.</h2 -</div> - -<div class="slide"> - <h1>Go, synchronized</h1> - - <h2>RPC client demux</h2> - -<pre> -func (client *Client) input() { - for { - resp := client.readResponse() - client.mutex.Lock() - c := client.pending[resp.Seq] - client.pending[resp.Seq] = c, false - client.mutex.Unlock() - if resp.Error != "" { - c.Error = os.ErrorString(resp.error) - } - resp.Decode(c.Reply) - c.Done <- c - } -} -</pre> - -<h2>Can create multiple Calls with same Done channel -and distinguish which finished by inspecting value sent on channel. -</h2> - -</div> - -<div class="slide"> - <h1>Goroutine demo</h1> - - <h2>Chain together 100,000 goroutines connected by 100,001 channels.</h2> - - <h2>Send a value to one end of the chain.</h2> - - <h2>Each passes it along, increments.</h2> - - <h2>Receive value out the other end of the chain.</h2> -</div> - - -<div class="slide"> - <h1>Go Status</h1> -</div> - -<div class="slide"> - <h1>Go Status</h1> - - <h2>Open source:</h2> - <ul> - <li>released on November 10, 2009 - <li>regular releases (~ weekly) - <li>all development done in public Mercurial repository - <li>outside contributions welcome - <li>two independent compiler implementations - <li>XML, JSON, HTTP, TLS/SSL, native RPC, (network channels,) ... - </ul> -</div> - -<div class="slide"> - <h1>Go Status</h1> - - <h2>Open source</h2> - - <h2>Portable:</h2> - <ul> - <li>FreeBSD, Linux, OS X (x86, x86-64) - <li>(in progress) Linux arm, Native Client x86, Windows x86. - </ul> -</div> - -<div class="slide"> - <h1>Go Status</h1> - - <h2>Open source</h2> - <h2>Portable</h2> - - <h2>Still in progress, experimental. Yet to come:</h2> - <ul> - <li>production garbage collector - <li>generics? - <li>exceptions? - <li>unions or sum types? - </ul> -</div> - -<div class="slide titlepage"> - <h1>Questions?</h1> - <br><br> - <center> - <img src="../gordon/bumper640x360.png"> - </center> - <br><br> - <div style="color: #ffcc00;"> - <!-- <h3><i>rsc@google.com</i></h3> --> - </div> -</div> - -</body></html> diff --git a/doc/talks/go_talk-20100323.html b/doc/talks/go_talk-20100323.html deleted file mode 100644 index 7330dd2ae..000000000 --- a/doc/talks/go_talk-20100323.html +++ /dev/null @@ -1,395 +0,0 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" - "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> -<head> -<title>Go Tech Talk</title> -<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> -<meta name="font-size-adjustment" content="-1" /> -<link rel="stylesheet" href="slidy.css" - type="text/css" media="screen, projection, print" /> -<script src="slidy.js" type="text/javascript"> -</script> -</head> -<body> -<!-- this defines the slide background --> - -<div class="background"> - - <div class="header"> - <!-- sized and colored via CSS --> - </div> - - <div class="footer"></div> - </div> - -<div class="slide titlepage"> -<br/> -<br/> -<img src="../go-logo-white.png" width="588px" height="217px"> -<br/> -<h1 style="padding-right: 0pt; margin-right: 0pt; color: #0066cc; font-size: 250%; border-bottom: 0px;">The Go Programming Language</h1> -<div style="color: #ffcc00;"> -<br/> -<h3>Sydney University<br/><br/>March 23, 2010</h3> -</div> -</div> - -<div class="slide"> - <h1>Go</h1> - - <h2>New</h2> - <h2>Experimental</h2> - <h2>Concurrent</h2> - <h2>Garbage Collected</h2> - <h2>Systems Language</h2> -</div> - -<div class="slide"> - <h1>Hello, world</h1> -<pre> -package main - -import "fmt" - -func main() { - fmt.Printf("Hello, 世界\n") -} -</pre> -</div> - -<div class="slide"> - <h1>Hello, world 2.0</h1> - - <h2>Serving <a href="http://localhost:8080/world">http://localhost:8080/world</a></h2> -<pre> -package main - -import ( - "fmt" - "http" -) - -func handler(c *http.Conn, r *http.Request) { - fmt.Fprintf(c, "Hello, %s.", r.URL.Path[1:]) -} - -func main() { - http.ListenAndServe(":8080", - http.HandlerFunc(handler)) -} -</pre> -</div> - -<div class="slide"> - <h1>New</h1> - - <h2>It's about two years old:</h2> - <ul> - <li>Design started in late 2007</li> - <li>Implementation starting to work mid-2008</li> - <li>Released as an open source project in November 2009</li> - <li>Development continues with an active community</li> - </ul> - - <h2>Why invent a new language? Older languages weren't designed for concurrency, but modern software needs it:</h2> - <ul> - <li>Large scale, networked computing, such as Google web search</li> - <li>Multi-core hardware</li> - </ul> -</div> - -<div class="slide"> - <h1>New</h1> - - <h2>Older languages are also frustrating on a day-to-day basis</h2> - <h2>Statically-typed languages (C, C++, Java) have issues:</h2> - <ul> - <li>Edit-Compile-Run cycle takes far too long</li> - <li>Type hierarchy can hurt as much as it helps</li> - </ul> -<div style="text-align:center"> -<img src="java-typing.png" width="800px" height="90px"><br> -</div> - - <h2>Dynamic languages (Python, JavaScript) fix some issues but introduce others:</h2> - <ul> - <li>No compilation means slow code</li> - <li>Runtime errors that should be caught statically</li> - </ul> - - <h2>Go has the lighter feel of a scripting language but is compiled</h2> -</div> - -<div class="slide"> - <h1>New</h1> - - <h2>Large C++ programs (e.g. Firefox, OpenOffice, Chromium) have enormous build times:</h2> - <ul> - <li>XKCD's #1 Programmer Excuse for Legitimately Slacking Off: "<a href="http://xkcd.com/303/">My Code's Compiling</a>"</li> - </ul> - - <h2>On a Mac (OS X 10.5.8, gcc 4.0.1):</h2> - <ul> - <li>C: <code>#include <stdio.h></code> reads 360 lines from 9 files</li> - <li>C++: <code>#include <iostream></code> reads 25,326 lines from 131 files</li> - <li>Objective-C: <code>#include <Carbon/Carbon.h></code> reads 124,730 lines from 689 files</li> - <li>We haven't done any real work yet!</li> - </ul> - - <h2>In Go: <code>import "fmt"</code> reads <i>one</i> file: 184 lines summarizing 7 packages</h2> -</div> - -<div class="slide"> - <h1>New</h1> - - <h2>Compilation demo</h2> -</div> - -<div class="slide"> - <h1>Experimental</h1> - - <h2>Go is still unproven</h2> - <h2>Language is still evolving</h2> - <h2>Package library is incomplete</h2> - <h2>Concurrent garbage collection is an active research problem</h2> - <h2>Reviving forgotten concepts:</h2> - <ul> - <li>Go's concurrency is strongly influenced by <i>Communicating Sequential Processes</i> (Hoare, 1978)</li> - <li>Go has types and interfaces, but no inheritance. It is arguably more object-oriented than previously mentioned languages, being closer to the original Smalltalk meaning (1970s)</li> - </ul> -</div> - -<div class="slide"> - <h1>Concurrent</h1> - - <h2>Unix philosophy: write <i>programs</i> that do one thing and do it well</h2> - <h2>Connect them with <i>pipes</i>:</h2> - <ul> - <li>How many lines of test code are there in the Go standard library?</li> - <li><code>find ~/go/src/pkg | grep _test.go$ | xargs wc -l</code></li> - </ul> - - <h2>Unlike other languages, Go makes it easy to:</h2> - <ul> - <li>Launch <i>goroutines</i></li> - <li>Connect them with <i>channels</i></li> - </ul> -</div> - -<div class="slide"> - <h1>Concurrent</h1> - - <h2>Start a new flow of control with the <code>go</code> keyword</h2> - <h2>Parallel computation is easy:</h2> -<pre> -func main() { - go expensiveComputation(x, y, z) - anotherExpensiveComputation(a, b, c) -} -</pre> - - <h2>Roughly speaking, a goroutine is like a thread, but lighter weight:</h2> - <ul> - <li>Goroutines have segmented stacks, and typically smaller stacks</li> - <li>This requires compiler support. Goroutines can't just be a C++ library on top of a thread library</li> - </ul> -</div> - -<div class="slide"> - <h1>Concurrent</h1> - - <h2>Consider web servers ("the C10k problem"):</h2> - <ul> - <li>"Thread per connection" approach is conceptually neat, but doesn't scale well in practice</li> - <li>What does scale well (event-driven callbacks, asynchronous APIs) are harder to understand, maintain, and debug</li> - <li>We think "goroutine per connection" can scale well, and is conceptually neat</li> - </ul> -<pre> - for { - rw := socket.Accept() - conn := newConn(rw, handler) - go conn.serve() - } -</pre> -</div> - -<div class="slide"> - <h1>Concurrent</h1> - - <h2>Let's look again at our simple parallel computation:</h2> -<pre> -func main() { - go expensiveComputation(x, y, z) - anotherExpensiveComputation(a, b, c) -} -</pre> - - <h2>This story is incomplete:</h2> - <ul> - <li>How do we know when the two computations are done?</li> - <li>What are their values?</li> - </ul> -</div> - -<div class="slide"> - <h1>Concurrent</h1> - - <h2>Goroutines communicate with other goroutines via channels</h2> -<pre> -func computeAndSend(ch chan int, x, y, z int) { - ch <- expensiveComputation(x, y, z) -} - -func main() { - ch := make(chan int) - go computeAndSend(ch, x, y, z) - v2 := anotherExpensiveComputation(a, b, c) - v1 := <-ch - fmt.Println(v1, v2) -} -</pre> - -</div> - -<div class="slide"> - <h1>Concurrent</h1> - - <h2>In traditional concurrent programs, you <i>communicate by sharing memory</i>. In Go, you <i>share memory by communicating</i>:</h2> - <ul> - <li>Communication (the <code><-</code> operator) is sharing and synchronization</li> - </ul> - - <h2>Threads and locks are concurrency primitives; CSP is a concurrency model:</h2> - <ul> - <li>Analogy: "Go To Statement Considered Harmful" (Dijsktra, 1968)</li> - <li><code>goto</code> is a control flow primitive; structured programming (<code>if</code> statements, <code>for</code> loops, function calls) is a control flow model</li> - </ul> - - <h2>Learning CSP changes the way you think about concurrent programming:</h2> - <ul> - <li>Every language has its grain. If your Go program uses mutexes, you're probably working against the grain</li> - </ul> -</div> - -<div class="slide"> - <h1>Garbage Collected</h1> - - <h2>Automatic memory management makes writing (and maintaining) programs easier</h2> - <h2>Especially in a concurrent world:</h2> - <ul> - <li>Who "owns" a shared piece of memory, and is responsible for destroying it?</li> - </ul> - - <h2>Large C++ programs usually end up with semi-automatic memory management anyway, via "smart pointers"</h2> - <h2>Mixing the two models can be problematic:</h2> - <ul> - <li>Browsers can leak memory easily; DOM elements are C++ objects, but JavaScript is garbage collected</li> - </ul> -</div> - -<div class="slide"> - <h1>Garbage Collected</h1> - - <h2>Go is also a safer language:</h2> - <ul> - <li>Pointers but no pointer arithmetic</li> - <li>No dangling pointers</li> - <li>Variables are zero-initialized</li> - <li>Array access is bounds-checked</li> - </ul> - - <h2>No buffer overflow exploits</h2> -</div> - -<div class="slide"> - <h1>Systems Language</h1> - - <h2>This just means you could write decently large programs in Go:</h2> - <ul> - <li>Web servers</li> - <li>Web browsers</li> - <li>Web crawlers</li> - <li>Search indexers</li> - <li>Databases</li> - <li>Word processors</li> - <li>Integrated Development Environments (IDEs)</li> - <li>Operating systems</li> - <li>...</li> - </ul> -</div> - -<div class="slide"> - <h1>Systems Language</h1> - - <h2>Garbage collection has a reputation for being "slower"</h2> - <h2>We're expecting Go to be slightly slower than optimized C, but faster than Java, depending on the task. Nonetheless:</h2> - <ul> - <li>Fast and buggy is worse than almost-as-fast and correct</li> - <li>It is easier to optimize a correct program than to correct an optimized program</li> - <li>Fundamentally, it's simply a trade-off we're willing to make</li> - </ul> - - <h2>Memory layout can drastically affect performance. These two designs are equivalent in Go, but significantly different in Java:</h2> -<pre> -type Point struct { X, Y int } -type Rect struct { P0, P1 Point } - -// or ... - -type Rect struct { X0, Y0, X1, Y1 int } -</pre> -</div> - -<div class="slide"> - <h1>Systems Language</h1> - - <h2>Quote from http://loadcode.blogspot.com/2009/12/go-vs-java.html</h2> - -<h2> -"[Git] is known to be very fast. It is written in C. A Java version -JGit was made. It was considerably slower. Handling of memory and lack -of unsigned types was some of the important reasons. -</h2> - -<h2>Shawn O. Pearce wrote on the git mailinglist:</h2> -<ul><li>"JGit struggles with not -having an efficient way to represent a SHA-1. C can just say "unsigned -char[20]" and have it inline into the container's memory allocation. A -byte[20] in Java will cost an *additional* 16 bytes of memory, and be -slower to access because the bytes themselves are in a different area -of memory from the container object. We try to work around it by -converting from a byte[20] to 5 ints, but that costs us machine -instructions" -</li></ul> - -<h2> -Like C, Go does allow unsigned types and defining data structures -containing other data structures as continuous blocks of memory." -</h2> -</div> - -<div class="slide"> - <h1>Go</h1> - - <h2>New</h2> - <h2>Experimental</h2> - <h2>Concurrent</h2> - <h2>Garbage Collected</h2> - <h2>Systems Language</h2> - - <h2>And more:</h2> - <ul> - <li>I haven't talked about the type system, interfaces, slices, closures, selects, ...</li> - <li>Documentation, mailing list, source code all online</li> - </ul> -</div> - -<div class="slide titlepage"> - <h1>Questions?</h1> - <br><br> - <center> - <img src="../gordon/bumper640x360.png" width="640px" height="360px"> - </center> -</div> - -</body></html> diff --git a/doc/talks/gofrontend-gcc-summit-2010.pdf b/doc/talks/gofrontend-gcc-summit-2010.pdf Binary files differdeleted file mode 100644 index 157fd7676..000000000 --- a/doc/talks/gofrontend-gcc-summit-2010.pdf +++ /dev/null diff --git a/doc/talks/io2010/balance.go b/doc/talks/io2010/balance.go deleted file mode 100644 index a3825cbc5..000000000 --- a/doc/talks/io2010/balance.go +++ /dev/null @@ -1,168 +0,0 @@ -// Copyright 2010 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -import ( - "container/heap" - "flag" - "fmt" - "math/rand" - "time" -) - -const nRequester = 100 -const nWorker = 10 - -var roundRobin = flag.Bool("r", false, "use round-robin scheduling") - -// Simulation of some work: just sleep for a while and report how long. -func op() int { - n := rand.Int63n(1e9) - time.Sleep(nWorker * n) - return int(n) -} - -type Request struct { - fn func() int - c chan int -} - -func requester(work chan Request) { - c := make(chan int) - for { - time.Sleep(rand.Int63n(nWorker * 2e9)) - work <- Request{op, c} - <-c - } -} - -type Worker struct { - i int - requests chan Request - pending int -} - -func (w *Worker) work(done chan *Worker) { - for { - req := <-w.requests - req.c <- req.fn() - done <- w - } -} - -type Pool []*Worker - -func (p Pool) Len() int { return len(p) } - -func (p Pool) Less(i, j int) bool { - return p[i].pending < p[j].pending -} - -func (p *Pool) Swap(i, j int) { - a := *p - a[i], a[j] = a[j], a[i] - a[i].i = i - a[j].i = j -} - -func (p *Pool) Push(x interface{}) { - a := *p - n := len(a) - a = a[0 : n+1] - w := x.(*Worker) - a[n] = w - w.i = n - *p = a -} - -func (p *Pool) Pop() interface{} { - a := *p - *p = a[0 : len(a)-1] - w := a[len(a)-1] - w.i = -1 // for safety - return w -} - -type Balancer struct { - pool Pool - done chan *Worker - i int -} - -func NewBalancer() *Balancer { - done := make(chan *Worker, nWorker) - b := &Balancer{make(Pool, 0, nWorker), done, 0} - for i := 0; i < nWorker; i++ { - w := &Worker{requests: make(chan Request, nRequester)} - heap.Push(&b.pool, w) - go w.work(b.done) - } - return b -} - -func (b *Balancer) balance(work chan Request) { - for { - select { - case req := <-work: - b.dispatch(req) - case w := <-b.done: - b.completed(w) - } - b.print() - } -} - -func (b *Balancer) print() { - sum := 0 - sumsq := 0 - for _, w := range b.pool { - fmt.Printf("%d ", w.pending) - sum += w.pending - sumsq += w.pending * w.pending - } - avg := float64(sum) / float64(len(b.pool)) - variance := float64(sumsq)/float64(len(b.pool)) - avg*avg - fmt.Printf(" %.2f %.2f\n", avg, variance) -} - -func (b *Balancer) dispatch(req Request) { - if *roundRobin { - w := b.pool[b.i] - w.requests <- req - w.pending++ - b.i++ - if b.i >= len(b.pool) { - b.i = 0 - } - return - } - - w := heap.Pop(&b.pool).(*Worker) - w.requests <- req - w.pending++ - // fmt.Printf("started %p; now %d\n", w, w.pending) - heap.Push(&b.pool, w) -} - -func (b *Balancer) completed(w *Worker) { - if *roundRobin { - w.pending-- - return - } - - w.pending-- - // fmt.Printf("finished %p; now %d\n", w, w.pending) - heap.Remove(&b.pool, w.i) - heap.Push(&b.pool, w) -} - -func main() { - flag.Parse() - work := make(chan Request) - for i := 0; i < nRequester; i++ { - go requester(work) - } - NewBalancer().balance(work) -} diff --git a/doc/talks/io2010/decrypt.go b/doc/talks/io2010/decrypt.go deleted file mode 100644 index e63418b1a..000000000 --- a/doc/talks/io2010/decrypt.go +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright 2010 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// This code differs from the slides in that it handles errors. - -package main - -import ( - "crypto/aes" - "crypto/cipher" - "compress/gzip" - "io" - "log" - "os" -) - -func EncryptAndGzip(dstfile, srcfile string, key, iv []byte) error { - r, err := os.Open(srcfile) - if err != nil { - return err - } - var w io.Writer - w, err = os.Create(dstfile) - if err != nil { - return err - } - c, err := aes.NewCipher(key) - if err != nil { - return err - } - w = cipher.StreamWriter{S: cipher.NewOFB(c, iv), W: w} - w2, err := gzip.NewWriter(w) - if err != nil { - return err - } - defer w2.Close() - _, err = io.Copy(w2, r) - return err -} - -func DecryptAndGunzip(dstfile, srcfile string, key, iv []byte) error { - f, err := os.Open(srcfile) - if err != nil { - return err - } - defer f.Close() - c, err := aes.NewCipher(key) - if err != nil { - return err - } - r := cipher.StreamReader{S: cipher.NewOFB(c, iv), R: f} - r2, err := gzip.NewReader(r) - if err != nil { - return err - } - w, err := os.Create(dstfile) - if err != nil { - return err - } - defer w.Close() - _, err = io.Copy(w, r2) - return err -} - -func main() { - err := EncryptAndGzip( - "/tmp/passwd.gz", - "/etc/passwd", - make([]byte, 16), - make([]byte, 16), - ) - if err != nil { - log.Fatal(err) - } - err = DecryptAndGunzip( - "/dev/stdout", - "/tmp/passwd.gz", - make([]byte, 16), - make([]byte, 16), - ) - if err != nil { - log.Fatal(err) - } -} diff --git a/doc/talks/io2010/encrypt.go b/doc/talks/io2010/encrypt.go deleted file mode 100644 index 57c888c74..000000000 --- a/doc/talks/io2010/encrypt.go +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright 2010 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// This code differs from the slides in that it handles errors. - -package main - -import ( - "crypto/aes" - "crypto/cipher" - "compress/gzip" - "io" - "log" - "os" -) - -func EncryptAndGzip(dstfile, srcfile string, key, iv []byte) error { - r, err := os.Open(srcfile) - if err != nil { - return err - } - var w io.WriteCloser - w, err = os.Create(dstfile) - if err != nil { - return err - } - defer w.Close() - w, err = gzip.NewWriter(w) - if err != nil { - return err - } - defer w.Close() - c, err := aes.NewCipher(key) - if err != nil { - return err - } - _, err = io.Copy(cipher.StreamWriter{S: cipher.NewOFB(c, iv), W: w}, r) - return err -} - -func main() { - err := EncryptAndGzip( - "/tmp/passwd.gz", - "/etc/passwd", - make([]byte, 16), - make([]byte, 16), - ) - if err != nil { - log.Fatal(err) - } -} diff --git a/doc/talks/io2010/eval1.go b/doc/talks/io2010/eval1.go deleted file mode 100644 index 582f43e8e..000000000 --- a/doc/talks/io2010/eval1.go +++ /dev/null @@ -1,227 +0,0 @@ -// Copyright 2010 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -import ( - "bufio" - "fmt" - "os" - "strconv" - "strings" -) - -// Generic expression parser/evaluator - -type Value interface { - String() string - BinaryOp(op string, y Value) Value -} - -type Parser struct { - precTab map[string]int - newVal func(string) Value - src string - pos int - tok string -} - -const alphanum = "_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" - -func (p *Parser) stop(c uint8) bool { - switch { - case p.pos >= len(p.src): - return true - case c == '"': - if p.src[p.pos] == '"' { - p.pos++ - return true - } - return false - case strings.IndexRune(alphanum, int(c)) >= 0: - return strings.IndexRune(alphanum, int(p.src[p.pos])) < 0 - } - return true -} - -func (p *Parser) next() { - // skip blanks - for ; p.pos < len(p.src) && p.src[p.pos] <= ' '; p.pos++ { - } - if p.pos >= len(p.src) { - p.tok = "" - return - } - start := p.pos - c := p.src[p.pos] - for p.pos < len(p.src) { - p.pos++ - if p.stop(c) { - break - } - } - p.tok = p.src[start:p.pos] -} - -func (p *Parser) binaryExpr(prec1 int) Value { - x := p.newVal(p.tok) - p.next() - for prec := p.precTab[p.tok]; prec >= prec1; prec-- { - for p.precTab[p.tok] == prec { - op := p.tok - p.next() - y := p.binaryExpr(prec + 1) - x = x.BinaryOp(op, y) - } - } - return x -} - -func Eval(precTab map[string]int, newVal func(string) Value, src string) Value { - var p Parser - p.precTab = precTab - p.newVal = newVal - p.src = src - p.next() - return p.binaryExpr(1) -} - -// Command-line expression evaluator - -func main() { - r := bufio.NewReader(os.Stdin) - for { - fmt.Printf("> ") - line, err := r.ReadString('\n') - if err != nil { - break - } - fmt.Printf("%s\n", Eval(precTab, trace(newVal), line)) - } -} - -// Custom grammar and values - -var precTab = map[string]int{ - "&&": 1, - "||": 2, - "==": 3, - "!=": 3, - "<": 3, - "<=": 3, - ">": 3, - ">=": 3, - "+": 4, - "-": 4, - "*": 5, - "/": 5, - "%": 5, -} - -func newVal(lit string) Value { - x, err := strconv.Atoi(lit) - if err == nil { - return Int(x) - } - b, err := strconv.ParseBool(lit) - if err == nil { - return Bool(b) - } - return Error(fmt.Sprintf("illegal literal '%s'", lit)) -} - -type Error string - -func (e Error) String() string { return string(e) } -func (e Error) BinaryOp(op string, y Value) Value { return e } - -type Int int - -func (x Int) String() string { return strconv.Itoa(int(x)) } -func (x Int) BinaryOp(op string, y Value) Value { - switch y := y.(type) { - case Error: - return y - case Int: - switch op { - case "+": - return x + y - case "-": - return x - y - case "*": - return x * y - case "/": - return x / y - case "%": - return x % y - case "==": - return Bool(x == y) - case "!=": - return Bool(x != y) - case "<": - return Bool(x < y) - case "<=": - return Bool(x <= y) - case ">": - return Bool(x > y) - case ">=": - return Bool(x >= y) - } - } - return Error(fmt.Sprintf("illegal operation: '%v %s %v'", x, op, y)) -} - -type Bool bool - -func (x Bool) String() string { return strconv.FormatBool(bool(x)) } -func (x Bool) BinaryOp(op string, y Value) Value { - switch y := y.(type) { - case Error: - return y - case Bool: - switch op { - case "&&": - return Bool(x && y) - case "||": - return Bool(x || y) - case "==": - return Bool(x == y) - case "!=": - return Bool(x != y) - } - } - return Error(fmt.Sprintf("illegal operation: '%v %s %v'", x, op, y)) -} - -func trace(newVal func(string) Value) func(string) Value { - return func(s string) Value { - v := newVal(s) - fmt.Printf("\tnewVal(%q) = %s\n", s, fmtv(v)) - return &traceValue{v} - } -} - -type traceValue struct { - Value -} - -func (x *traceValue) BinaryOp(op string, y Value) Value { - z := x.Value.BinaryOp(op, y.(*traceValue).Value) - fmt.Printf("\t%s.BinaryOp(%q, %s) = %s\n", fmtv(x.Value), op, fmtv(y.(*traceValue).Value), fmtv(z)) - return &traceValue{z} -} - -func (x *traceValue) String() string { - s := x.Value.String() - fmt.Printf("\t%s.String() = %#v\n", fmtv(x.Value), s) - return s -} - -func fmtv(v Value) string { - t := fmt.Sprintf("%T", v) - if i := strings.LastIndex(t, "."); i >= 0 { // strip package - t = t[i+1:] - } - return fmt.Sprintf("%s(%#v)", t, v) -} diff --git a/doc/talks/io2010/eval2.go b/doc/talks/io2010/eval2.go deleted file mode 100644 index 6f826e12d..000000000 --- a/doc/talks/io2010/eval2.go +++ /dev/null @@ -1,259 +0,0 @@ -// Copyright 2010 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -import ( - "bufio" - "fmt" - "os" - "strconv" - "strings" -) - -// Generic expression parser/evaluator - -type Value interface { - String() string - BinaryOp(op string, y Value) Value -} - -type Parser struct { - precTab map[string]int - newVal func(string) Value - src string - pos int - tok string -} - -const alphanum = "_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" - -func (p *Parser) stop(c uint8) bool { - switch { - case p.pos >= len(p.src): - return true - case c == '"': - if p.src[p.pos] == '"' { - p.pos++ - return true - } - return false - case strings.IndexRune(alphanum, int(c)) >= 0: - return strings.IndexRune(alphanum, int(p.src[p.pos])) < 0 - } - return true -} - -func (p *Parser) next() { - // skip blanks - for ; p.pos < len(p.src) && p.src[p.pos] <= ' '; p.pos++ { - } - if p.pos >= len(p.src) { - p.tok = "" - return - } - start := p.pos - c := p.src[p.pos] - for p.pos < len(p.src) { - p.pos++ - if p.stop(c) { - break - } - } - p.tok = p.src[start:p.pos] -} - -func (p *Parser) binaryExpr(prec1 int) Value { - x := p.newVal(p.tok) - p.next() - for prec := p.precTab[p.tok]; prec >= prec1; prec-- { - for p.precTab[p.tok] == prec { - op := p.tok - p.next() - y := p.binaryExpr(prec + 1) - x = x.BinaryOp(op, y) - } - } - return x -} - -func Eval(precTab map[string]int, newVal func(string) Value, src string) Value { - var p Parser - p.precTab = precTab - p.newVal = newVal - p.src = src - p.next() - return p.binaryExpr(1) -} - -// Command-line expression evaluator - -func main() { - r := bufio.NewReader(os.Stdin) - for { - fmt.Printf("> ") - line, err := r.ReadString('\n') - if err != nil { - break - } - fmt.Printf("%s\n", Eval(precTab, trace(newVal), line)) - } -} - -// Custom grammar and values - -var precTab = map[string]int{ - "&&": 1, - "||": 2, - "==": 3, - "!=": 3, - "<": 3, - "<=": 3, - ">": 3, - ">=": 3, - "+": 4, - "-": 4, - "*": 5, - "/": 5, - "%": 5, -} - -func newVal(lit string) Value { - x, err := strconv.Atoi(lit) - if err == nil { - return Int(x) - } - b, err := strconv.ParseBool(lit) - if err == nil { - return Bool(b) - } - s, err := strconv.Unquote(lit) - if err == nil { - return String(s) - } - return Error(fmt.Sprintf("illegal literal '%s'", lit)) -} - -type Error string - -func (e Error) String() string { return string(e) } -func (e Error) BinaryOp(op string, y Value) Value { return e } - -type Int int - -func (x Int) String() string { return strconv.Itoa(int(x)) } -func (x Int) BinaryOp(op string, y Value) Value { - switch y := y.(type) { - case Error: - return y - case String: - switch op { - case "*": - return String(strings.Repeat(string(y), int(x))) - } - case Int: - switch op { - case "+": - return x + y - case "-": - return x - y - case "*": - return x * y - case "/": - return x / y - case "%": - return x % y - case "==": - return Bool(x == y) - case "!=": - return Bool(x != y) - case "<": - return Bool(x < y) - case "<=": - return Bool(x <= y) - case ">": - return Bool(x > y) - case ">=": - return Bool(x >= y) - } - } - return Error(fmt.Sprintf("illegal operation: '%v %s %v'", x, op, y)) -} - -type Bool bool - -func (x Bool) String() string { return strconv.FormatBool(bool(x)) } -func (x Bool) BinaryOp(op string, y Value) Value { - switch y := y.(type) { - case Error: - return y - case Bool: - switch op { - case "&&": - return Bool(x && y) - case "||": - return Bool(x || y) - case "==": - return Bool(x == y) - case "!=": - return Bool(x != y) - } - } - return Error(fmt.Sprintf("illegal operation: '%v %s %v'", x, op, y)) -} - -type String string - -func (x String) String() string { return strconv.Quote(string(x)) } -func (x String) BinaryOp(op string, y Value) Value { - switch y := y.(type) { - case Error: - return y - case Int: - switch op { - case "*": - return String(strings.Repeat(string(x), int(y))) - } - case String: - switch op { - case "+": - return x + y - case "<": - return Bool(x < y) - } - } - return Error(fmt.Sprintf("illegal operation: '%v %s %v'", x, op, y)) -} - -func trace(newVal func(string) Value) func(string) Value { - return func(s string) Value { - v := newVal(s) - fmt.Printf("\tnewVal(%q) = %s\n", s, fmtv(v)) - return &traceValue{v} - } -} - -type traceValue struct { - Value -} - -func (x *traceValue) BinaryOp(op string, y Value) Value { - z := x.Value.BinaryOp(op, y.(*traceValue).Value) - fmt.Printf("\t%s.BinaryOp(%q, %s) = %s\n", fmtv(x.Value), op, fmtv(y.(*traceValue).Value), fmtv(z)) - return &traceValue{z} -} - -func (x *traceValue) String() string { - s := x.Value.String() - fmt.Printf("\t%s.String() = %#v\n", fmtv(x.Value), s) - return s -} - -func fmtv(v Value) string { - t := fmt.Sprintf("%T", v) - if i := strings.LastIndex(t, "."); i >= 0 { // strip package - t = t[i+1:] - } - return fmt.Sprintf("%s(%#v)", t, v) -} diff --git a/doc/talks/io2010/talk.pdf b/doc/talks/io2010/talk.pdf Binary files differdeleted file mode 100644 index aff42c21d..000000000 --- a/doc/talks/io2010/talk.pdf +++ /dev/null diff --git a/doc/talks/io2011/Real_World_Go.pdf b/doc/talks/io2011/Real_World_Go.pdf Binary files differdeleted file mode 100644 index 2a187116b..000000000 --- a/doc/talks/io2011/Real_World_Go.pdf +++ /dev/null diff --git a/doc/talks/io2011/Writing_Web_Apps_in_Go.pdf b/doc/talks/io2011/Writing_Web_Apps_in_Go.pdf Binary files differdeleted file mode 100644 index ca4702ee9..000000000 --- a/doc/talks/io2011/Writing_Web_Apps_in_Go.pdf +++ /dev/null diff --git a/doc/talks/java-typing.png b/doc/talks/java-typing.png Binary files differdeleted file mode 100644 index 54abf0186..000000000 --- a/doc/talks/java-typing.png +++ /dev/null diff --git a/doc/talks/slidy.css b/doc/talks/slidy.css deleted file mode 100644 index e9ff53218..000000000 --- a/doc/talks/slidy.css +++ /dev/null @@ -1,277 +0,0 @@ -/* http://www.w3.org/Talks/Tools/Slidy/slidy.css - - Copyright (c) 2005 W3C (MIT, ERCIM, Keio), All Rights Reserved. - W3C liability, trademark, document use and software licensing - rules apply, see: - - http://www.w3.org/Consortium/Legal/copyright-documents - http://www.w3.org/Consortium/Legal/copyright-software -*/ -body -{ - margin: 0 0 0 0; - padding: 0 0 0 0; - width: 100%; - height: 100%; - color: black; - background-color: white; - font-family: "Lucida Sans", "Lucida Grande", Lucida, sans-serif; - font-size: 14pt; -} - -.hidden { display: none; visibility: hidden } - -div.toolbar { - position: fixed; z-index: 200; - top: auto; bottom: 0; left: 0; right: 0; - height: 1.2em; text-align: right; - padding-left: 1em; - padding-right: 1em; - font-size: 60%; - color: red; background: rgb(240,240,240); -} - -div.background { - display: none; -} - -div.handout { - margin-left: 20px; - margin-right: 20px; -} - -div.slide.titlepage { - color: white; - background: black; - text-align: center; -} - -div.slide { - z-index: 20; - margin: 0 0 0 0; - padding-top: 0; - padding-bottom: 0; - padding-left: 20px; - padding-right: 20px; - border-width: 0; - top: 0; - bottom: 0; - left: 0; - right: 0; - line-height: 120%; - background-color: transparent; -} - -/* this rule is hidden from IE 6 and below which don't support + selector */ -div.slide + div[class].slide { page-break-before: always;} - -div.slide h1 { - padding-left: 20px; - padding-right: 20px; - padding-top: 10px; - padding-bottom: 10px; - margin-top: 0; - margin-left: 0; - margin-right: 0; - margin-bottom: 0.5em; - border-bottom: 4px solid #36c; - display: block; - font-size: 160%; - line-height: 1.2em; -} - -div.slide h2 { - font-size:120%; - line-height: 1.2em; -} - -div.toc { - position: absolute; - top: auto; - bottom: 4em; - left: 4em; - right: auto; - width: 60%; - max-width: 30em; - height: 30em; - border: solid thin black; - padding: 1em; - background: rgb(240,240,240); - color: black; - z-index: 300; - overflow: auto; - display: block; - visibility: visible; -} - -div.toc-heading { - width: 100%; - border-bottom: solid 1px rgb(180,180,180); - margin-bottom: 1em; - text-align: center; -} - -pre { - font-size: 120%; - font-weight: bold; - line-height: 140%; - padding-top: 0.2em; - padding-bottom: 0.2em; - padding-left: 1em; - padding-right: 1em; -/* - border-style: solid; - border-left-width: 1em; - border-top-width: thin; - border-right-width: thin; - border-bottom-width: thin; - border-color: #95ABD0; -*/ - color: #0F398D; - background-color: #fff8f8; -} - -@media print { - div.slide { - display: block; - visibility: visible; - position: relative; - border-top-style: solid; - border-top-width: thin; - border-top-color: black; - } - div.slide pre { font-size: 60%; padding-left: 0.5em; } - div.handout { display: block; visibility: visible; } -} - -blockquote { font-style: italic } - -img { background-color: transparent } - -p.copyright { font-size: smaller } - -.center { text-align: center } -.footnote { font-size: smaller; margin-left: 2em; } - -a img { border-width: 0; border-style: none } - -a:visited { color: navy } -a:link { color: navy } -a:hover { color: red; text-decoration: underline } -a:active { color: red; text-decoration: underline } - -a {text-decoration: none} -.navbar a:link {color: white} -.navbar a:visited {color: yellow} -.navbar a:active {color: red} -.navbar a:hover {color: red} - -ul { list-style-type: square; } -ul ul { list-style-type: disc; } -ul ul ul { list-style-type: circle; } -ul ul ul ul { list-style-type: disc; } -li { margin-left: 2em; margin-top: 0.5em; } -li li { font-size: 85%; font-style: italic } -li li li { font-size: 85%; font-style: normal } - -div dt -{ - margin-left: 0; - margin-top: 1em; - margin-bottom: 0.5em; - font-weight: bold; -} -div dd -{ - margin-left: 2em; - margin-bottom: 0.5em; -} - - -p,pre,ul,ol,blockquote,h2,h3,h4,h5,h6,dl,table { - margin-left: 1em; - margin-right: 1em; -} - -p.subhead { font-weight: bold; margin-top: 2em; } - -p.smaller { font-size: smaller } - -td,th { padding: 0.2em } - -ul { - margin: 0.5em 1.5em 0.5em 1.5em; - padding: 0; -} - -ol { - margin: 0.5em 1.5em 0.5em 1.5em; - padding: 0; -} - -ul { list-style-type: square; } -ul ul { list-style-type: disc; } -ul ul ul { list-style-type: circle; } -ul ul ul ul { list-style-type: disc; } - -ul li { - list-style: square; - //margin: 0.1em 0em 0.6em 0; - padding: 0 0 0 0; - line-height: 140%; -} - -ol li { - margin: 0.1em 0em 0.6em 1.5em; - padding: 0 0 0 0px; - line-height: 140%; - list-style-type: decimal; -} - -li ul li { - font-size: 85%; - font-style: italic; - list-style-type: disc; - background: transparent; - padding: 0 0 0 0; -} -li li ul li { - font-size: 85%; - font-style: normal; - list-style-type: circle; - background: transparent; - padding: 0 0 0 0; -} -li li li ul li { - list-style-type: disc; - background: transparent; - padding: 0 0 0 0; -} - -li ol li { - list-style-type: decimal; -} - - -li li ol li { - list-style-type: decimal; -} - -/* - setting class="outline on ol or ul makes it behave as an - ouline list where blocklevel content in li elements is - hidden by default and can be expanded or collapsed with - mouse click. Set class="expand" on li to override default -*/ - -ol.outline li:hover { cursor: pointer } -ol.outline li.nofold:hover { cursor: default } - -ul.outline li:hover { cursor: pointer } -ul.outline li.nofold:hover { cursor: default } - -ol.outline { list-style:decimal; } -ol.outline ol { list-style-type:lower-alpha } - -/* for slides with class "title" in table of contents */ -a.titleslide { font-weight: bold; font-style: italic } diff --git a/doc/talks/slidy.js b/doc/talks/slidy.js deleted file mode 100644 index 6a5561a6c..000000000 --- a/doc/talks/slidy.js +++ /dev/null @@ -1,2772 +0,0 @@ -/* http://www.w3.org/Talks/Tools/Slidy/slidy.js - - Copyright (c) 2005 W3C (MIT, ERCIM, Keio), All Rights Reserved. - W3C liability, trademark, document use and software licensing - rules apply, see: - - http://www.w3.org/Consortium/Legal/copyright-documents - http://www.w3.org/Consortium/Legal/copyright-software -*/ - -var ns_pos = (typeof window.pageYOffset!='undefined'); -var khtml = ((navigator.userAgent).indexOf("KHTML") >= 0 ? true : false); -var opera = ((navigator.userAgent).indexOf("Opera") >= 0 ? true : false); -var ie7 = (!ns_pos && navigator.userAgent.indexOf("MSIE 7") != -1); - -window.onload = startup; // equivalent to onload on body element - -// IE only event handlers to ensure all slides are printed -// I don't yet know how to emulate these for other browsers -window.onbeforeprint = beforePrint; -window.onafterprint = afterPrint; - -// hack to hide slides while loading -setTimeout(hideAll, 50); - -function hideAll() -{ - if (document.body) - document.body.style.visibility = "hidden"; - else - setTimeout(hideAll, 50); -} - -var slidenum = 0; // integer slide count: 0, 1, 2, ... -var slides; // set to array of slide div's -var slideNumElement; // element containing slide number -var notes; // set to array of handout div's -var backgrounds; // set to array of background div's -var toolbar; // element containing toolbar -var title; // document title -var lastShown = null; // last incrementally shown item -var eos = null; // span element for end of slide indicator -var toc = null; // table of contents -var outline = null; // outline element with the focus -var selectedTextLen; // length of drag selection on document - -var viewAll = 0; // 1 to view all slides + handouts -var wantToolbar = 1; // 0 if toolbar isn't wanted -var mouseClickEnabled = true; // enables left click for next slide -var scrollhack = 0; // IE work around for position: fixed - -var helpAnchor; // used for keyboard focus hack in showToolbar() -var helpPage = "http://www.w3.org/Talks/Tools/Slidy/help.html"; -var helpText = "Navigate with mouse click, space bar, Cursor Left/Right, " + - "or Pg Up and Pg Dn. Use S and B to change font size."; - -var sizeIndex = 0; -var sizeAdjustment = 0; -var sizes = new Array("10pt", "12pt", "14pt", "16pt", "18pt", "20pt", - "22pt", "24pt", "26pt", "28pt", "30pt", "32pt"); - -var okayForIncremental = incrementalElementList(); - -// needed for efficient resizing -var lastWidth = 0; -var lastHeight = 0; - -// Needed for cross browser support for relative width/height on -// object elements. The work around is to save width/height attributes -// and then to recompute absolute width/height dimensions on resizing -var objects; - -// updated to language specified by html file -var lang = "en"; - -//var localize = {}; - -// for each language there is an associative array -var strings_es = { - "slide":"pág.", - "help?":"Ayuda", - "contents?":"Índice", - "table of contents":"tabla de contenidos", - "Table of Contents":"Tabla de Contenidos", - "restart presentation":"Reiniciar presentación", - "restart?":"Inicio" - }; - -strings_es[helpText] = - "Utilice el ratón, barra espaciadora, teclas Izda/Dhca, " + - "o Re pág y Av pág. Use S y B para cambiar el tamaño de fuente."; - -var strings_nl = { - "slide":"pagina", - "help?":"Help?", - "contents?":"Inhoud?", - "table of contents":"inhoudsopgave", - "Table of Contents":"Inhoudsopgave", - "restart presentation":"herstart presentatie", - "restart?":"Herstart?" - }; - -strings_nl[helpText] = - "Navigeer d.m.v. het muis, spatiebar, Links/Rechts toetsen, " + - "of PgUp en PgDn. Gebruik S en B om de karaktergrootte te veranderen."; - -var strings_de = { - "slide":"Seite", - "help?":"Hilfe", - "contents?":"Übersicht", - "table of contents":"Inhaltsverzeichnis", - "Table of Contents":"Inhaltsverzeichnis", - "restart presentation":"Präsentation neu starten", - "restart?":"Neustart" - }; - -strings_de[helpText] = - "Benutzen Sie die Maus, Leerschlag, die Cursortasten links/rechts" + - "oder Page up/Page Down zum Wechseln der Seiten und S und B für die Schriftgrösse."; - -var strings_pl = { - "slide":"slajd", - "help?":"pomoc?", - "contents?":"spis treści?", - "table of contents":"spis treści", - "Table of Contents":"Spis Treści", - "restart presentation":"Restartuj prezentację", - "restart?":"restart?" - }; - -strings_pl[helpText] = - "Zmieniaj slajdy klikając myszą, naciskając spację, strzałki lewo/prawo" + - "lub PgUp / PgDn. Użyj klawiszy S i B, aby zmienić rozmiar czczionki."; - -var strings_fr = { - "slide":"page", - "help?":"Aide", - "contents?":"Index", - "table of contents":"table des matières", - "Table of Contents":"Table des matières", - "restart presentation":"Recommencer l'exposé", - "restart?":"Début" - }; - -strings_fr[helpText] = - "Naviguez avec la souris, la barre d'espace, les flèches" + - "gauche/droite ou les touches Pg Up, Pg Dn. Utilisez " + - "les touches S et B pour modifier la taille de la police."; - -var strings_hu = { - "slide":"oldal", - "help?":"segítség", - "contents?":"tartalom", - "table of contents":"tartalomjegyzék", - "Table of Contents":"Tartalomjegyzék", - "restart presentation":"bemutató újraindítása", - "restart?":"újraindítás" - }; - -strings_hu[helpText] = - "Az oldalak közti lépkedéshez kattintson az egérrel, vagy használja a szóköz, a bal, vagy a jobb nyíl, " + - "illetve a Page Down, Page Up billentyűket. Az S és a B billentyűkkel változtathatja a szöveg méretét."; - -var strings_it = { - "slide":"pag.", - "help?":"Aiuto", - "contents?":"Indice", - "table of contents":"indice", - "Table of Contents":"Indice", - "restart presentation":"Ricominciare la presentazione", - "restart?":"Inizio" - }; - -strings_it[helpText] = - "Navigare con mouse, barra spazio, frecce sinistra/destra o " + - "PgUp e PgDn. Usare S e B per cambiare la dimensione dei caratteri."; - -var strings_el = { - "slide":"σελίδα", - "help?":"βοήθεια;", - "contents?":"περιεχόμενα;", - "table of contents":"πίνακας περιεχομένων", - "Table of Contents":"Πίνακας Περιεχομένων", - "restart presentation":"επανεκκίνηση παρουσίασης", - "restart?":"επανεκκίνηση;" - }; - -strings_el[helpText] = - "Πλοηγηθείτε με το κλίκ του ποντικιού, το space, τα βέλη αριστερά/δεξιά, " + - "ή Page Up και Page Down. Χρησιμοποιήστε τα πλήκτρα S και B για να αλλάξετε " + - "το μέγεθος της γραμματοσειράς."; - -var strings_ja = { - "slide":"スライド", - "help?":"ヘルプ", - "contents?":"目次", - "table of contents":"目次を表示", - "Table of Contents":"目次", - "restart presentation":"最初から再生", - "restart?":"最初から" -}; - -strings_ja[helpText] = - "マウス左クリック ・ スペース ・ 左右キー " + - "または Page Up ・ Page Downで操作, S ・ Bでフォントサイズ変更"; - - -// each such language array is declared in the localize array -// used indirectly as in help.innerHTML = "help".localize(); -var localize = { - "es":strings_es, - "nl":strings_nl, - "de":strings_de, - "pl":strings_pl, - "fr":strings_fr, - "hu":strings_hu, - "it":strings_it, - "el":strings_el, - "jp":strings_ja - }; - -/* general initialization */ -function startup() -{ - // find human language from html element - // for use in localizing strings - lang = document.body.parentNode.getAttribute("lang"); - - if (!lang) - lang = document.body.parentNode.getAttribute("xml:lang"); - - if (!lang) - lang = "en"; - - document.body.style.visibility = "visible"; - title = document.title; - toolbar = addToolbar(); - wrapImplicitSlides(); - slides = collectSlides(); - notes = collectNotes(); - objects = document.body.getElementsByTagName("object"); - backgrounds = collectBackgrounds(); - patchAnchors(); - - slidenum = findSlideNumber(location.href); - window.offscreenbuffering = true; - sizeAdjustment = findSizeAdjust(); - hideImageToolbar(); // suppress IE image toolbar popup - initOutliner(); // activate fold/unfold support - - if (slides.length > 0) - { - var slide = slides[slidenum]; - slide.style.position = "absolute"; - - if (slidenum > 0) - { - setVisibilityAllIncremental("visible"); - lastShown = previousIncrementalItem(null); - setEosStatus(true); - } - else - { - lastShown = null; - setVisibilityAllIncremental("hidden"); - setEosStatus(!nextIncrementalItem(lastShown)); - } - - setLocation(); - } - - toc = tableOfContents(); - hideTableOfContents(); - - // bind event handlers - document.onclick = mouseButtonClick; - document.onmouseup = mouseButtonUp; - document.onkeydown = keyDown; - window.onresize = resized; - window.onscroll = scrolled; - singleSlideView(); - - setLocation(); - resized(); - - if (ie7) - setTimeout("ieHack()", 100); - - showToolbar(); -} - -// add localize method to all strings for use -// as in help.innerHTML = "help".localize(); -String.prototype.localize = function() -{ - if (this == "") - return this; - - // try full language code, e.g. en-US - var s, lookup = localize[lang]; - - if (lookup) - { - s = lookup[this]; - - if (s) - return s; - } - - // try en if undefined for en-US - var lg = lang.split("-"); - - if (lg.length > 1) - { - lookup = localize[lg[0]]; - - if (lookup) - { - s = lookup[this]; - - if (s) - return s; - } - } - - // otherwise string as is - return this; -} - -// suppress IE's image toolbar pop up -function hideImageToolbar() -{ - if (!ns_pos) - { - var images = document.getElementsByTagName("IMG"); - - for (var i = 0; i < images.length; ++i) - images[i].setAttribute("galleryimg", "no"); - } -} - -// hack to persuade IE to compute correct document height -// as needed for simulating fixed positioning of toolbar -function ieHack() -{ - window.resizeBy(0,-1); - window.resizeBy(0, 1); -} - -// Firefox reload SVG bug work around -function reload(e) -{ - if (!e) - var e = window.event; - - hideBackgrounds(); - setTimeout("document.reload();", 100); - - stopPropagation(e); - e.cancel = true; - e.returnValue = false; - - return false; -} - -// Safari and Konqueror don't yet support getComputedStyle() -// and they always reload page when location.href is updated -function isKHTML() -{ - var agent = navigator.userAgent; - return (agent.indexOf("KHTML") >= 0 ? true : false); -} - -function resized() -{ - var width = 0; - - if ( typeof( window.innerWidth ) == 'number' ) - width = window.innerWidth; // Non IE browser - else if (document.documentElement && document.documentElement.clientWidth) - width = document.documentElement.clientWidth; // IE6 - else if (document.body && document.body.clientWidth) - width = document.body.clientWidth; // IE4 - - var height = 0; - - if ( typeof( window.innerHeight ) == 'number' ) - height = window.innerHeight; // Non IE browser - else if (document.documentElement && document.documentElement.clientHeight) - height = document.documentElement.clientHeight; // IE6 - else if (document.body && document.body.clientHeight) - height = document.body.clientHeight; // IE4 - - if (height && (width/height > 1.05*1024/768)) - { - width = height * 1024.0/768; - } - - // IE fires onresize even when only font size is changed! - // so we do a check to avoid blocking < and > actions - if (width != lastWidth || height != lastHeight) - { - if (width >= 1100) - sizeIndex = 5; // 4 - else if (width >= 1000) - sizeIndex = 4; // 3 - else if (width >= 800) - sizeIndex = 3; // 2 - else if (width >= 600) - sizeIndex = 2; // 1 - else if (width) - sizeIndex = 0; - - // add in font size adjustment from meta element e.g. - // <meta name="font-size-adjustment" content="-2" /> - // useful when slides have too much content ;-) - - if (0 <= sizeIndex + sizeAdjustment && - sizeIndex + sizeAdjustment < sizes.length) - sizeIndex = sizeIndex + sizeAdjustment; - - // enables cross browser use of relative width/height - // on object elements for use with SVG and Flash media - adjustObjectDimensions(width, height); - - document.body.style.fontSize = sizes[sizeIndex]; - - lastWidth = width; - lastHeight = height; - - // force reflow to work around Mozilla bug - //if (ns_pos) - { - var slide = slides[slidenum]; - hideSlide(slide); - showSlide(slide); - } - - // force correct positioning of toolbar - refreshToolbar(200); - } -} - -function scrolled() -{ - if (toolbar && !ns_pos && !ie7) - { - hackoffset = scrollXOffset(); - // hide toolbar - toolbar.style.display = "none"; - - // make it reappear later - if (scrollhack == 0 && !viewAll) - { - setTimeout(showToolbar, 1000); - scrollhack = 1; - } - } -} - -// used to ensure IE refreshes toolbar in correct position -function refreshToolbar(interval) -{ - if (!ns_pos && !ie7) - { - hideToolbar(); - setTimeout(showToolbar, interval); - } -} - -// restores toolbar after short delay -function showToolbar() -{ - if (wantToolbar) - { - if (!ns_pos) - { - // adjust position to allow for scrolling - var xoffset = scrollXOffset(); - toolbar.style.left = xoffset; - toolbar.style.right = xoffset; - - // determine vertical scroll offset - //var yoffset = scrollYOffset(); - - // bottom is doc height - window height - scroll offset - //var bottom = documentHeight() - lastHeight - yoffset - - //if (yoffset > 0 || documentHeight() > lastHeight) - // bottom += 16; // allow for height of scrollbar - - toolbar.style.bottom = 0; //bottom; - } - - toolbar.style.display = "block"; - toolbar.style.visibility = "visible"; - } - - scrollhack = 0; - - - // set the keyboard focus to the help link on the - // toolbar to ensure that document has the focus - // IE doesn't always work with window.focus() - // and this hack has benefit of Enter for help - - try - { - if (!opera) - helpAnchor.focus(); - } - catch (e) - { - } -} - -function test() -{ - var s = "docH: " + documentHeight() + - " winH: " + lastHeight + - " yoffset: " + scrollYOffset() + - " toolbot: " + (documentHeight() - lastHeight - scrollYOffset()); - - //alert(s); - - var slide = slides[slidenum]; - // IE getAttribute requires "class" to be "className" - var name = ns_pos ? "class" : "className"; - var style = (slide.currentStyle ? slide.currentStyle["backgroundColor"] : - document.defaultView.getComputedStyle(slide, '').getPropertyValue("background-color")); - alert("class='" + slide.getAttribute(name) + "' backgroundColor: " + style); -} - -function hideToolbar() -{ - toolbar.style.display = "none"; - toolbar.style.visibility = "hidden"; - window.focus(); -} - -// invoked via F key -function toggleToolbar() -{ - if (!viewAll) - { - if (toolbar.style.display == "none") - { - toolbar.style.display = "block"; - toolbar.style.visibility = "visible"; - wantToolbar = 1; - } - else - { - toolbar.style.display = "none"; - toolbar.style.visibility = "hidden"; - wantToolbar = 0; - } - } -} - -function scrollXOffset() -{ - if (window.pageXOffset) - return self.pageXOffset; - - if (document.documentElement && - document.documentElement.scrollLeft) - return document.documentElement.scrollLeft; - - if (document.body) - return document.body.scrollLeft; - - return 0; -} - - -function scrollYOffset() -{ - if (window.pageYOffset) - return self.pageYOffset; - - if (document.documentElement && - document.documentElement.scrollTop) - return document.documentElement.scrollTop; - - if (document.body) - return document.body.scrollTop; - - return 0; -} - -// looking for a way to determine height of slide content -// the slide itself is set to the height of the window -function optimizeFontSize() -{ - var slide = slides[slidenum]; - - //var dh = documentHeight(); //getDocHeight(document); - var dh = slide.scrollHeight; - var wh = getWindowHeight(); - var u = 100 * dh / wh; - - alert("window utilization = " + u + "% (doc " - + dh + " win " + wh + ")"); -} - -function getDocHeight(doc) // from document object -{ - if (!doc) - doc = document; - - if (doc && doc.body && doc.body.offsetHeight) - return doc.body.offsetHeight; // ns/gecko syntax - - if (doc && doc.body && doc.body.scrollHeight) - return doc.body.scrollHeight; - - alert("couldn't determine document height"); -} - -function getWindowHeight() -{ - if ( typeof( window.innerHeight ) == 'number' ) - return window.innerHeight; // Non IE browser - - if (document.documentElement && document.documentElement.clientHeight) - return document.documentElement.clientHeight; // IE6 - - if (document.body && document.body.clientHeight) - return document.body.clientHeight; // IE4 -} - - - -function documentHeight() -{ - var sh, oh; - - sh = document.body.scrollHeight; - oh = document.body.offsetHeight; - - if (sh && oh) - { - return (sh > oh ? sh : oh); - } - - // no idea! - return 0; -} - -function smaller() -{ - if (sizeIndex > 0) - { - --sizeIndex; - } - - toolbar.style.display = "none"; - document.body.style.fontSize = sizes[sizeIndex]; - var slide = slides[slidenum]; - hideSlide(slide); - showSlide(slide); - setTimeout(showToolbar, 300); -} - -function bigger() -{ - if (sizeIndex < sizes.length - 1) - { - ++sizeIndex; - } - - toolbar.style.display = "none"; - document.body.style.fontSize = sizes[sizeIndex]; - var slide = slides[slidenum]; - hideSlide(slide); - showSlide(slide); - setTimeout(showToolbar, 300); -} - -// enables cross browser use of relative width/height -// on object elements for use with SVG and Flash media -// with thanks to Ivan Herman for the suggestion -function adjustObjectDimensions(width, height) -{ - for( var i = 0; i < objects.length; i++ ) - { - var obj = objects[i]; - var mimeType = obj.getAttribute("type"); - - if (mimeType == "image/svg+xml" || mimeType == "application/x-shockwave-flash") - { - if ( !obj.initialWidth ) - obj.initialWidth = obj.getAttribute("width"); - - if ( !obj.initialHeight ) - obj.initialHeight = obj.getAttribute("height"); - - if ( obj.initialWidth && obj.initialWidth.charAt(obj.initialWidth.length-1) == "%" ) - { - var w = parseInt(obj.initialWidth.slice(0, obj.initialWidth.length-1)); - var newW = width * (w/100.0); - obj.setAttribute("width",newW); - } - - if ( obj.initialHeight && obj.initialHeight.charAt(obj.initialHeight.length-1) == "%" ) - { - var h = parseInt(obj.initialHeight.slice(0, obj.initialHeight.length-1)); - var newH = height * (h/100.0); - obj.setAttribute("height", newH); - } - } - } -} - -function cancel(event) -{ - if (event) - { - event.cancel = true; - event.returnValue = false; - - if (event.preventDefault) - event.preventDefault(); - } - - return false; -} - -// See e.g. http://www.quirksmode.org/js/events/keys.html for keycodes -function keyDown(event) -{ - var key; - - if (!event) - var event = window.event; - - // kludge around NS/IE differences - if (window.event) - key = window.event.keyCode; - else if (event.which) - key = event.which; - else - return true; // Yikes! unknown browser - - // ignore event if key value is zero - // as for alt on Opera and Konqueror - if (!key) - return true; - - // check for concurrent control/command/alt key - // but are these only present on mouse events? - - if (event.ctrlKey || event.altKey || event.metaKey) - return true; - - // dismiss table of contents if visible - if (isShownToc() && key != 9 && key != 16 && key != 38 && key != 40) - { - hideTableOfContents(); - - if (key == 27 || key == 84 || key == 67) - return cancel(event); - } - - if (key == 34) // Page Down - { - nextSlide(false); - return cancel(event); - } - else if (key == 33) // Page Up - { - previousSlide(false); - return cancel(event); - } - else if (key == 32) // space bar - { - nextSlide(true); - return cancel(event); - } - else if (key == 37 || key == 38) // Left arrow || Up arrow - { - previousSlide(!event.shiftKey); - return cancel(event); - } - else if (key == 36) // Home - { - firstSlide(); - return cancel(event); - } - else if (key == 35) // End - { - lastSlide(); - return cancel(event); - } - else if (key == 39 || key == 40) // Right arrow || Down arrow - { - nextSlide(!event.shiftKey); - return cancel(event); - } - else if (key == 13) // Enter - { - if (outline) - { - if (outline.visible) - fold(outline); - else - unfold(outline); - - return cancel(event); - } - } - else if (key == 188) // < for smaller fonts - { - smaller(); - return cancel(event); - } - else if (key == 190) // > for larger fonts - { - bigger(); - return cancel(event); - } - else if (key == 189 || key == 109) // - for smaller fonts - { - smaller(); - return cancel(event); - } - else if (key == 187 || key == 191 || key == 107) // = + for larger fonts - { - bigger(); - return cancel(event); - } - else if (key == 83) // S for smaller fonts - { - smaller(); - return cancel(event); - } - else if (key == 66) // B for larger fonts - { - bigger(); - return cancel(event); - } - else if (key == 90) // Z for last slide - { - lastSlide(); - return cancel(event); - } - else if (key == 70) // F for toggle toolbar - { - toggleToolbar(); - return cancel(event); - } - else if (key == 65) // A for toggle view single/all slides - { - toggleView(); - return cancel(event); - } - else if (key == 75) // toggle action of left click for next page - { - mouseClickEnabled = !mouseClickEnabled; - alert((mouseClickEnabled ? "enabled" : "disabled") + " mouse click advance"); - return cancel(event); - } - else if (key == 84 || key == 67) // T or C for table of contents - { - if (toc) - showTableOfContents(); - - return cancel(event); - } - else if (key == 72) // H for help - { - window.location = helpPage; - return cancel(event); - } - - //else if (key == 93) // Windows menu key - //alert("lastShown is " + lastShown); - //else alert("key code is "+ key); - - - return true; -} - -// make note of length of selected text -// as this evaluates to zero in click event -function mouseButtonUp(e) -{ - selectedTextLen = getSelectedText().length; -} - -// right mouse button click is reserved for context menus -// it is more reliable to detect rightclick than leftclick -function mouseButtonClick(e) -{ - var rightclick = false; - var leftclick = false; - var middleclick = false; - var target; - - if (!e) - var e = window.event; - - if (e.target) - target = e.target; - else if (e.srcElement) - target = e.srcElement; - - // work around Safari bug - if (target.nodeType == 3) - target = target.parentNode; - - if (e.which) // all browsers except IE - { - leftclick = (e.which == 1); - middleclick = (e.which == 2); - rightclick = (e.which == 3); - } - else if (e.button) - { - // Konqueror gives 1 for left, 4 for middle - // IE6 gives 0 for left and not 1 as I expected - - if (e.button == 4) - middleclick = true; - - // all browsers agree on 2 for right button - rightclick = (e.button == 2); - } - else leftclick = true; - - // dismiss table of contents - hideTableOfContents(); - - if (selectedTextLen > 0) - { - stopPropagation(e); - e.cancel = true; - e.returnValue = false; - return false; - } - - // check if target is something that probably want's clicks - // e.g. embed, object, input, textarea, select, option - - if (mouseClickEnabled && leftclick && - target.nodeName != "EMBED" && - target.nodeName != "OBJECT" && - target.nodeName != "INPUT" && - target.nodeName != "TEXTAREA" && - target.nodeName != "SELECT" && - target.nodeName != "OPTION") - { - nextSlide(true); - stopPropagation(e); - e.cancel = true; - e.returnValue = false; - } -} - -function previousSlide(incremental) -{ - if (!viewAll) - { - var slide; - - if ((incremental || slidenum == 0) && lastShown != null) - { - lastShown = hidePreviousItem(lastShown); - setEosStatus(false); - } - else if (slidenum > 0) - { - slide = slides[slidenum]; - hideSlide(slide); - - slidenum = slidenum - 1; - slide = slides[slidenum]; - setVisibilityAllIncremental("visible"); - lastShown = previousIncrementalItem(null); - setEosStatus(true); - showSlide(slide); - } - - setLocation(); - - if (!ns_pos) - refreshToolbar(200); - } -} - -function nextSlide(incremental) -{ - if (!viewAll) - { - var slide, last = lastShown; - - if (incremental || slidenum == slides.length - 1) - lastShown = revealNextItem(lastShown); - - if ((!incremental || lastShown == null) && slidenum < slides.length - 1) - { - slide = slides[slidenum]; - hideSlide(slide); - - slidenum = slidenum + 1; - slide = slides[slidenum]; - lastShown = null; - setVisibilityAllIncremental("hidden"); - showSlide(slide); - } - else if (!lastShown) - { - if (last && incremental) - lastShown = last; - } - - setLocation(); - - setEosStatus(!nextIncrementalItem(lastShown)); - - if (!ns_pos) - refreshToolbar(200); - } -} - -// to first slide with nothing revealed -// i.e. state at start of presentation -function firstSlide() -{ - if (!viewAll) - { - var slide; - - if (slidenum != 0) - { - slide = slides[slidenum]; - hideSlide(slide); - - slidenum = 0; - slide = slides[slidenum]; - lastShown = null; - setVisibilityAllIncremental("hidden"); - showSlide(slide); - } - - setEosStatus(!nextIncrementalItem(lastShown)); - setLocation(); - } -} - - -// to last slide with everything revealed -// i.e. state at end of presentation -function lastSlide() -{ - if (!viewAll) - { - var slide; - - lastShown = null; //revealNextItem(lastShown); - - if (lastShown == null && slidenum < slides.length - 1) - { - slide = slides[slidenum]; - hideSlide(slide); - slidenum = slides.length - 1; - slide = slides[slidenum]; - setVisibilityAllIncremental("visible"); - lastShown = previousIncrementalItem(null); - - showSlide(slide); - } - else - { - setVisibilityAllIncremental("visible"); - lastShown = previousIncrementalItem(null); - } - - setEosStatus(true); - setLocation(); - } -} - -function setEosStatus(state) -{ - if (eos) - eos.style.color = (state ? "rgb(240,240,240)" : "red"); -} - -function showSlide(slide) -{ - syncBackground(slide); - window.scrollTo(0,0); - slide.style.visibility = "visible"; - slide.style.display = "block"; -} - -function hideSlide(slide) -{ - slide.style.visibility = "hidden"; - slide.style.display = "none"; -} - -function beforePrint() -{ - showAllSlides(); - hideToolbar(); -} - -function afterPrint() -{ - if (!viewAll) - { - singleSlideView(); - showToolbar(); - } -} - -function printSlides() -{ - beforePrint(); - window.print(); - afterPrint(); -} - -function toggleView() -{ - if (viewAll) - { - singleSlideView(); - showToolbar(); - viewAll = 0; - } - else - { - showAllSlides(); - hideToolbar(); - viewAll = 1; - } -} - -// prepare for printing -function showAllSlides() -{ - var slide; - - for (var i = 0; i < slides.length; ++i) - { - slide = slides[i]; - - slide.style.position = "relative"; - slide.style.borderTopStyle = "solid"; - slide.style.borderTopWidth = "thin"; - slide.style.borderTopColor = "black"; - - try { - if (i == 0) - slide.style.pageBreakBefore = "avoid"; - else - slide.style.pageBreakBefore = "always"; - } - catch (e) - { - //do nothing - } - - setVisibilityAllIncremental("visible"); - showSlide(slide); - } - - var note; - - for (var i = 0; i < notes.length; ++i) - { - showSlide(notes[i]); - } - - // no easy way to render background under each slide - // without duplicating the background divs for each slide - // therefore hide backgrounds to avoid messing up slides - hideBackgrounds(); -} - -// restore after printing -function singleSlideView() -{ - var slide; - - for (var i = 0; i < slides.length; ++i) - { - slide = slides[i]; - - slide.style.position = "absolute"; - - if (i == slidenum) - { - slide.style.borderStyle = "none"; - showSlide(slide); - } - else - { - slide.style.borderStyle = "none"; - hideSlide(slide); - } - } - - setVisibilityAllIncremental("visible"); - lastShown = previousIncrementalItem(null); - - var note; - - for (var i = 0; i < notes.length; ++i) - { - hideSlide(notes[i]); - } -} - -// the string str is a whitespace separated list of tokens -// test if str contains a particular token, e.g. "slide" -function hasToken(str, token) -{ - if (str) - { - // define pattern as regular expression - var pattern = /\w+/g; - - // check for matches - // place result in array - var result = str.match(pattern); - - // now check if desired token is present - for (var i = 0; i < result.length; i++) - { - if (result[i] == token) - return true; - } - } - - return false; -} - -function getClassList(element) -{ - if (typeof window.pageYOffset =='undefined') - return element.getAttribute("className"); - - return element.getAttribute("class"); -} - -function hasClass(element, name) -{ - var regexp = new RegExp("(^| )" + name + "\W*"); - - if (regexp.test(getClassList(element))) - return true; - - return false; - -} - -function removeClass(element, name) -{ - // IE getAttribute requires "class" to be "className" - var clsname = ns_pos ? "class" : "className"; - var clsval = element.getAttribute(clsname); - - var regexp = new RegExp("(^| )" + name + "\W*"); - - if (clsval) - { - clsval = clsval.replace(regexp, ""); - element.setAttribute(clsname, clsval); - } -} - -function addClass(element, name) -{ - if (!hasClass(element, name)) - { - // IE getAttribute requires "class" to be "className" - var clsname = ns_pos ? "class" : "className"; - var clsval = element.getAttribute(clsname); - element.setAttribute(clsname, (clsval ? clsval + " " + name : name)); - } -} - -// wysiwyg editors make it hard to use div elements -// e.g. amaya loses the div when you copy and paste -// this function wraps div elements around implicit -// slides which start with an h1 element and continue -// up to the next heading or div element -function wrapImplicitSlides() -{ - var i, heading, node, next, div; - var headings = document.getElementsByTagName("h1"); - - if (!headings) - return; - - for (i = 0; i < headings.length; ++i) - { - heading = headings[i]; - - if (heading.parentNode != document.body) - continue; - - node = heading.nextSibling; - - div = document.createElement("div"); - div.setAttribute((ns_pos ? "class" : "className"), "slide"); - document.body.replaceChild(div, heading); - div.appendChild(heading); - - while (node) - { - if (node.nodeType == 1 && // an element - (node.nodeName == "H1" || - node.nodeName == "h1" || - node.nodeName == "DIV" || - node.nodeName == "div")) - break; - - next = node.nextSibling; - node = document.body.removeChild(node); - div.appendChild(node); - node = next; - } - } -} - -// return new array of all slides -function collectSlides() -{ - var slides = new Array(); - var divs = document.body.getElementsByTagName("div"); - - for (var i = 0; i < divs.length; ++i) - { - div = divs.item(i); - - if (hasClass(div, "slide")) - { - // add slide to collection - slides[slides.length] = div; - - // hide each slide as it is found - div.style.display = "none"; - div.style.visibility = "hidden"; - - // add dummy <br/> at end for scrolling hack - var node1 = document.createElement("br"); - div.appendChild(node1); - var node2 = document.createElement("br"); - div.appendChild(node2); - } - else if (hasClass(div, "background")) - { // work around for Firefox SVG reload bug - // which otherwise replaces 1st SVG graphic with 2nd - div.style.display = "block"; - } - } - - return slides; -} - -// return new array of all <div class="handout"> -function collectNotes() -{ - var notes = new Array(); - var divs = document.body.getElementsByTagName("div"); - - for (var i = 0; i < divs.length; ++i) - { - div = divs.item(i); - - if (hasClass(div, "handout")) - { - // add slide to collection - notes[notes.length] = div; - - // hide handout notes as they are found - div.style.display = "none"; - div.style.visibility = "hidden"; - } - } - - return notes; -} - -// return new array of all <div class="background"> -// including named backgrounds e.g. class="background titlepage" -function collectBackgrounds() -{ - var backgrounds = new Array(); - var divs = document.body.getElementsByTagName("div"); - - for (var i = 0; i < divs.length; ++i) - { - div = divs.item(i); - - if (hasClass(div, "background")) - { - // add slide to collection - backgrounds[backgrounds.length] = div; - - // hide named backgrounds as they are found - // e.g. class="background epilog" - if (getClassList(div) != "background") - { - div.style.display = "none"; - div.style.visibility = "hidden"; - } - } - } - - return backgrounds; -} - -// show just the backgrounds pertinent to this slide -function syncBackground(slide) -{ - var background; - var bgColor; - - if (slide.currentStyle) - bgColor = slide.currentStyle["backgroundColor"]; - else if (document.defaultView) - { - var styles = document.defaultView.getComputedStyle(slide,null); - - if (styles) - bgColor = styles.getPropertyValue("background-color"); - else // broken implementation probably due Safari or Konqueror - { - //alert("defective implementation of getComputedStyle()"); - bgColor = "transparent"; - } - } - else - bgColor == "transparent"; - - if (bgColor == "transparent") - { - var slideClass = getClassList(slide); - - for (var i = 0; i < backgrounds.length; i++) - { - background = backgrounds[i]; - - var bgClass = getClassList(background); - - if (matchingBackground(slideClass, bgClass)) - { - background.style.display = "block"; - background.style.visibility = "visible"; - } - else - { - background.style.display = "none"; - background.style.visibility = "hidden"; - } - } - } - else // forcibly hide all backgrounds - hideBackgrounds(); -} - -function hideBackgrounds() -{ - for (var i = 0; i < backgrounds.length; i++) - { - background = backgrounds[i]; - background.style.display = "none"; - background.style.visibility = "hidden"; - } -} - -// compare classes for slide and background -function matchingBackground(slideClass, bgClass) -{ - if (bgClass == "background") - return true; - - // define pattern as regular expression - var pattern = /\w+/g; - - // check for matches and place result in array - var result = slideClass.match(pattern); - - // now check if desired name is present for background - for (var i = 0; i < result.length; i++) - { - if (hasToken(bgClass, result[i])) - return true; - } - - return false; -} - -// left to right traversal of root's content -function nextNode(root, node) -{ - if (node == null) - return root.firstChild; - - if (node.firstChild) - return node.firstChild; - - if (node.nextSibling) - return node.nextSibling; - - for (;;) - { - node = node.parentNode; - - if (!node || node == root) - break; - - if (node && node.nextSibling) - return node.nextSibling; - } - - return null; -} - -// right to left traversal of root's content -function previousNode(root, node) -{ - if (node == null) - { - node = root.lastChild; - - if (node) - { - while (node.lastChild) - node = node.lastChild; - } - - return node; - } - - if (node.previousSibling) - { - node = node.previousSibling; - - while (node.lastChild) - node = node.lastChild; - - return node; - } - - if (node.parentNode != root) - return node.parentNode; - - return null; -} - -// HTML elements that can be used with class="incremental" -// note that you can also put the class on containers like -// up, ol, dl, and div to make their contents appear -// incrementally. Upper case is used since this is what -// browsers report for HTML node names (text/html). -function incrementalElementList() -{ - var inclist = new Array(); - inclist["P"] = true; - inclist["PRE"] = true; - inclist["LI"] = true; - inclist["BLOCKQUOTE"] = true; - inclist["DT"] = true; - inclist["DD"] = true; - inclist["H2"] = true; - inclist["H3"] = true; - inclist["H4"] = true; - inclist["H5"] = true; - inclist["H6"] = true; - inclist["SPAN"] = true; - inclist["ADDRESS"] = true; - inclist["TABLE"] = true; - inclist["TR"] = true; - inclist["TH"] = true; - inclist["TD"] = true; - inclist["IMG"] = true; - inclist["OBJECT"] = true; - return inclist; -} - -function nextIncrementalItem(node) -{ - var slide = slides[slidenum]; - - for (;;) - { - node = nextNode(slide, node); - - if (node == null || node.parentNode == null) - break; - - if (node.nodeType == 1) // ELEMENT - { - if (node.nodeName == "BR") - continue; - - if (hasClass(node, "incremental") - && okayForIncremental[node.nodeName]) - return node; - - if (hasClass(node.parentNode, "incremental") - && !hasClass(node, "non-incremental")) - return node; - } - } - - return node; -} - -function previousIncrementalItem(node) -{ - var slide = slides[slidenum]; - - for (;;) - { - node = previousNode(slide, node); - - if (node == null || node.parentNode == null) - break; - - if (node.nodeType == 1) - { - if (node.nodeName == "BR") - continue; - - if (hasClass(node, "incremental") - && okayForIncremental[node.nodeName]) - return node; - - if (hasClass(node.parentNode, "incremental") - && !hasClass(node, "non-incremental")) - return node; - } - } - - return node; -} - -// set visibility for all elements on current slide with -// a parent element with attribute class="incremental" -function setVisibilityAllIncremental(value) -{ - var node = nextIncrementalItem(null); - - while (node) - { - node.style.visibility = value; - node = nextIncrementalItem(node); - } -} - -// reveal the next hidden item on the slide -// node is null or the node that was last revealed -function revealNextItem(node) -{ - node = nextIncrementalItem(node); - - if (node && node.nodeType == 1) // an element - node.style.visibility = "visible"; - - return node; -} - - -// exact inverse of revealNextItem(node) -function hidePreviousItem(node) -{ - if (node && node.nodeType == 1) // an element - node.style.visibility = "hidden"; - - return previousIncrementalItem(node); -} - - -/* set click handlers on all anchors */ -function patchAnchors() -{ - var anchors = document.body.getElementsByTagName("a"); - - for (var i = 0; i < anchors.length; ++i) - { - anchors[i].onclick = clickedAnchor; - } -} - -function clickedAnchor(e) -{ - if (!e) - var e = window.event; - - // compare this.href with location.href - // for link to another slide in this doc - - if (pageAddress(this.href) == pageAddress(location.href)) - { - // yes, so find new slide number - var newslidenum = findSlideNumber(this.href); - - if (newslidenum != slidenum) - { - slide = slides[slidenum]; - hideSlide(slide); - slidenum = newslidenum; - slide = slides[slidenum]; - showSlide(slide); - setLocation(); - } - } - else if (this.target == null) - location.href = this.href; - - this.blur(); - stopPropagation(e); -} - -function pageAddress(uri) -{ - var i = uri.indexOf("#"); - - // check if anchor is entire page - - if (i < 0) - return uri; // yes - - return uri.substr(0, i); -} - -function showSlideNumber() -{ - slideNumElement.innerHTML = "slide".localize() + " " + - (slidenum + 1) + "/" + slides.length; -} - -function setLocation() -{ - var uri = pageAddress(location.href); - - //if (slidenum > 0) - uri = uri + "#(" + (slidenum+1) + ")"; - - if (uri != location.href && !khtml) - location.href = uri; - - document.title = title + " (" + (slidenum+1) + ")"; - //document.title = (slidenum+1) + ") " + slideName(slidenum); - - showSlideNumber(); -} - -// find current slide based upon location -// first find target anchor and then look -// for associated div element enclosing it -// finally map that to slide number -function findSlideNumber(uri) -{ - // first get anchor from page location - - var i = uri.indexOf("#"); - - // check if anchor is entire page - - if (i < 0) - return 0; // yes - - var anchor = unescape(uri.substr(i+1)); - - // now use anchor as XML ID to find target - var target = document.getElementById(anchor); - - if (!target) - { - // does anchor look like "(2)" for slide 2 ?? - // where first slide is (1) - var re = /\((\d)+\)/; - - if (anchor.match(re)) - { - var num = parseInt(anchor.substring(1, anchor.length-1)); - - if (num > slides.length) - num = 1; - - if (--num < 0) - num = 0; - - return num; - } - - // accept [2] for backwards compatibility - re = /\[(\d)+\]/; - - if (anchor.match(re)) - { - var num = parseInt(anchor.substring(1, anchor.length-1)); - - if (num > slides.length) - num = 1; - - if (--num < 0) - num = 0; - - return num; - } - - // oh dear unknown anchor - return 0; - } - - // search for enclosing slide - - while (true) - { - // browser coerces html elements to uppercase! - if (target.nodeName.toLowerCase() == "div" && - hasClass(target, "slide")) - { - // found the slide element - break; - } - - // otherwise try parent element if any - - target = target.parentNode; - - if (!target) - { - return 0; // no luck! - } - }; - - for (i = 0; i < slides.length; ++i) - { - if (slides[i] == target) - return i; // success - } - - // oh dear still no luck - return 0; -} - -// find slide name from first h1 element -// default to document title + slide number -function slideName(index) -{ - var name = null; - var slide = slides[index]; - - var heading = findHeading(slide); - - if (heading) - name = extractText(heading); - - if (!name) - name = title + "(" + (index + 1) + ")"; - - name.replace(/\&/g, "&"); - name.replace(/\</g, "<"); - name.replace(/\>/g, ">"); - - return name; -} - -// find first h1 element in DOM tree -function findHeading(node) -{ - if (!node || node.nodeType != 1) - return null; - - if (node.nodeName == "H1" || node.nodeName == "h1") - return node; - - var child = node.firstChild; - - while (child) - { - node = findHeading(child); - - if (node) - return node; - - child = child.nextSibling; - } - - return null; -} - -// recursively extract text from DOM tree -function extractText(node) -{ - if (!node) - return ""; - - // text nodes - if (node.nodeType == 3) - return node.nodeValue; - - // elements - if (node.nodeType == 1) - { - node = node.firstChild; - var text = ""; - - while (node) - { - text = text + extractText(node); - node = node.nextSibling; - } - - return text; - } - - return ""; -} - - -// find copyright text from meta element -function findCopyright() -{ - var name, content; - var meta = document.getElementsByTagName("meta"); - - for (var i = 0; i < meta.length; ++i) - { - name = meta[i].getAttribute("name"); - content = meta[i].getAttribute("content"); - - if (name == "copyright") - return content; - } - - return null; -} - -function findSizeAdjust() -{ - var name, content, offset; - var meta = document.getElementsByTagName("meta"); - - for (var i = 0; i < meta.length; ++i) - { - name = meta[i].getAttribute("name"); - content = meta[i].getAttribute("content"); - - if (name == "font-size-adjustment") - return 1 * content; - } - - return 0; -} - -function addToolbar() -{ - var slideCounter, page; - - var toolbar = createElement("div"); - toolbar.setAttribute("class", "toolbar"); - - if (ns_pos) // a reasonably behaved browser - { - var right = document.createElement("div"); - right.setAttribute("style", "float: right; text-align: right"); - - slideCounter = document.createElement("div") - slideCounter.innerHTML = "slide".localize() + " n/m"; - right.appendChild(slideCounter); - toolbar.appendChild(right); - - var left = document.createElement("div"); - left.setAttribute("style", "text-align: left"); - - // global end of slide indicator - eos = document.createElement("span"); - eos.innerHTML = "* "; - left.appendChild(eos); - - var help = document.createElement("a"); - help.setAttribute("href", helpPage); - help.setAttribute("title", helpText.localize()); - help.innerHTML = "help?".localize(); - left.appendChild(help); - helpAnchor = help; // save for focus hack - - var gap1 = document.createTextNode(" "); - left.appendChild(gap1); - - var contents = document.createElement("a"); - contents.setAttribute("href", "javascript:toggleTableOfContents()"); - contents.setAttribute("title", "table of contents".localize()); - contents.innerHTML = "contents?".localize(); - left.appendChild(contents); - - var gap2 = document.createTextNode(" "); - left.appendChild(gap2); - - var i = location.href.indexOf("#"); - - // check if anchor is entire page - - if (i > 0) - page = location.href.substr(0, i); - else - page = location.href; - - var start = document.createElement("a"); - start.setAttribute("href", page); - start.setAttribute("title", "restart presentation".localize()); - start.innerHTML = "restart?".localize(); -// start.setAttribute("href", "javascript:printSlides()"); -// start.setAttribute("title", "print all slides".localize()); -// start.innerHTML = "print!".localize(); - left.appendChild(start); - - var copyright = findCopyright(); - - if (copyright) - { - var span = document.createElement("span"); - span.innerHTML = copyright; - span.style.color = "black"; - span.style.marginLeft = "4em"; - left.appendChild(span); - } - - toolbar.appendChild(left); - } - else // IE so need to work around its poor CSS support - { - toolbar.style.position = (ie7 ? "fixed" : "absolute"); - toolbar.style.zIndex = "200"; - toolbar.style.width = "99.9%"; - toolbar.style.height = "1.2em"; - toolbar.style.top = "auto"; - toolbar.style.bottom = "0"; - toolbar.style.left = "0"; - toolbar.style.right = "0"; - toolbar.style.textAlign = "left"; - toolbar.style.fontSize = "60%"; - toolbar.style.color = "red"; - toolbar.borderWidth = 0; - toolbar.style.background = "rgb(240,240,240)"; - - // would like to have help text left aligned - // and page counter right aligned, floating - // div's don't work, so instead use nested - // absolutely positioned div's. - - var sp = document.createElement("span"); - sp.innerHTML = " * "; - toolbar.appendChild(sp); - eos = sp; // end of slide indicator - - var help = document.createElement("a"); - help.setAttribute("href", helpPage); - help.setAttribute("title", helpText.localize()); - help.innerHTML = "help?".localize(); - toolbar.appendChild(help); - helpAnchor = help; // save for focus hack - - var gap1 = document.createTextNode(" "); - toolbar.appendChild(gap1); - - var contents = document.createElement("a"); - contents.setAttribute("href", "javascript:toggleTableOfContents()"); - contents.setAttribute("title", "table of contents".localize()); - contents.innerHTML = "contents?".localize(); - toolbar.appendChild(contents); - - var gap2 = document.createTextNode(" "); - toolbar.appendChild(gap2); - - var i = location.href.indexOf("#"); - - // check if anchor is entire page - - if (i > 0) - page = location.href.substr(0, i); - else - page = location.href; - - var start = document.createElement("a"); - start.setAttribute("href", page); - start.setAttribute("title", "restart presentation".localize()); - start.innerHTML = "restart?".localize(); -// start.setAttribute("href", "javascript:printSlides()"); -// start.setAttribute("title", "print all slides".localize()); -// start.innerHTML = "print!".localize(); - toolbar.appendChild(start); - - var copyright = findCopyright(); - - if (copyright) - { - var span = document.createElement("span"); - span.innerHTML = copyright; - span.style.color = "black"; - span.style.marginLeft = "2em"; - toolbar.appendChild(span); - } - - slideCounter = document.createElement("div") - slideCounter.style.position = "absolute"; - slideCounter.style.width = "auto"; //"20%"; - slideCounter.style.height = "1.2em"; - slideCounter.style.top = "auto"; - slideCounter.style.bottom = 0; - slideCounter.style.right = "0"; - slideCounter.style.textAlign = "right"; - slideCounter.style.color = "red"; - slideCounter.style.background = "rgb(240,240,240)"; - - slideCounter.innerHTML = "slide".localize() + " n/m"; - toolbar.appendChild(slideCounter); - } - - // ensure that click isn't passed through to the page - toolbar.onclick = stopPropagation; - document.body.appendChild(toolbar); - slideNumElement = slideCounter; - setEosStatus(false); - - return toolbar; -} - -function isShownToc() -{ - if (toc && toc.style.visible == "visible") - return true; - - return false; -} - -function showTableOfContents() -{ - if (toc) - { - if (toc.style.visibility != "visible") - { - toc.style.visibility = "visible"; - toc.style.display = "block"; - toc.focus(); - - if (ie7 && slidenum == 0) - setTimeout("ieHack()", 100); - } - else - hideTableOfContents(); - } -} - -function hideTableOfContents() -{ - if (toc && toc.style.visibility != "hidden") - { - toc.style.visibility = "hidden"; - toc.style.display = "none"; - - try - { - if (!opera) - helpAnchor.focus(); - } - catch (e) - { - } - } -} - -function toggleTableOfContents() -{ - if (toc) - { - if (toc.style.visible != "visible") - showTableOfContents(); - else - hideTableOfContents(); - } -} - -// called on clicking toc entry -function gotoEntry(e) -{ - var target; - - if (!e) - var e = window.event; - - if (e.target) - target = e.target; - else if (e.srcElement) - target = e.srcElement; - - // work around Safari bug - if (target.nodeType == 3) - target = target.parentNode; - - if (target && target.nodeType == 1) - { - var uri = target.getAttribute("href"); - - if (uri) - { - //alert("going to " + uri); - var slide = slides[slidenum]; - hideSlide(slide); - slidenum = findSlideNumber(uri); - slide = slides[slidenum]; - lastShown = null; - setLocation(); - setVisibilityAllIncremental("hidden"); - setEosStatus(!nextIncrementalItem(lastShown)); - showSlide(slide); - //target.focus(); - - try - { - if (!opera) - helpAnchor.focus(); - } - catch (e) - { - } - } - } - - hideTableOfContents(e); - if (ie7) ieHack(); - stopPropagation(e); - return cancel(e); -} - -// called onkeydown for toc entry -function gotoTocEntry(event) -{ - var key; - - if (!event) - var event = window.event; - - // kludge around NS/IE differences - if (window.event) - key = window.event.keyCode; - else if (event.which) - key = event.which; - else - return true; // Yikes! unknown browser - - // ignore event if key value is zero - // as for alt on Opera and Konqueror - if (!key) - return true; - - // check for concurrent control/command/alt key - // but are these only present on mouse events? - - if (event.ctrlKey || event.altKey) - return true; - - if (key == 13) - { - var uri = this.getAttribute("href"); - - if (uri) - { - //alert("going to " + uri); - var slide = slides[slidenum]; - hideSlide(slide); - slidenum = findSlideNumber(uri); - slide = slides[slidenum]; - lastShown = null; - setLocation(); - setVisibilityAllIncremental("hidden"); - setEosStatus(!nextIncrementalItem(lastShown)); - showSlide(slide); - //target.focus(); - - try - { - if (!opera) - helpAnchor.focus(); - } - catch (e) - { - } - } - - hideTableOfContents(); - if (ie7) ieHack(); - return cancel(event); - } - - if (key == 40 && this.next) - { - this.next.focus(); - return cancel(event); - } - - if (key == 38 && this.previous) - { - this.previous.focus(); - return cancel(event); - } - - return true; -} - -function isTitleSlide(slide) -{ - return hasClass(slide, "title"); -} - -// create div element with links to each slide -function tableOfContents() -{ - var toc = document.createElement("div"); - addClass(toc, "toc"); - //toc.setAttribute("tabindex", "0"); - - var heading = document.createElement("div"); - addClass(heading, "toc-heading"); - heading.innerHTML = "Table of Contents".localize(); - - heading.style.textAlign = "center"; - heading.style.width = "100%"; - heading.style.margin = "0"; - heading.style.marginBottom = "1em"; - heading.style.borderBottomStyle = "solid"; - heading.style.borderBottomColor = "rgb(180,180,180)"; - heading.style.borderBottomWidth = "1px"; - - toc.appendChild(heading); - var previous = null; - - for (var i = 0; i < slides.length; ++i) - { - var title = hasClass(slides[i], "title"); - var num = document.createTextNode((i + 1) + ". "); - - toc.appendChild(num); - - var a = document.createElement("a"); - a.setAttribute("href", "#(" + (i+1) + ")"); - - if (title) - addClass(a, "titleslide"); - - var name = document.createTextNode(slideName(i)); - a.appendChild(name); - a.onclick = gotoEntry; - a.onkeydown = gotoTocEntry; - a.previous = previous; - - if (previous) - previous.next = a; - - toc.appendChild(a); - - if (i == 0) - toc.first = a; - - if (i < slides.length - 1) - { - var br = document.createElement("br"); - toc.appendChild(br); - } - - previous = a; - } - - toc.focus = function () { - if (this.first) - this.first.focus(); - } - - toc.onclick = function (e) { - e||(e=window.event); - hideTableOfContents(); - stopPropagation(e); - - if (e.cancel != undefined) - e.cancel = true; - - if (e.returnValue != undefined) - e.returnValue = false; - - return false; - }; - - toc.style.position = "absolute"; - toc.style.zIndex = "300"; - toc.style.width = "60%"; - toc.style.maxWidth = "30em"; - toc.style.height = "30em"; - toc.style.overflow = "auto"; - toc.style.top = "auto"; - toc.style.right = "auto"; - toc.style.left = "4em"; - toc.style.bottom = "4em"; - toc.style.padding = "1em"; - toc.style.background = "rgb(240,240,240)"; - toc.style.borderStyle = "solid"; - toc.style.borderWidth = "2px"; - toc.style.fontSize = "60%"; - - document.body.insertBefore(toc, document.body.firstChild); - return toc; -} - -function replaceByNonBreakingSpace(str) -{ - for (var i = 0; i < str.length; ++i) - str[i] = 160; -} - - -function initOutliner() -{ - var items = document.getElementsByTagName("LI"); - - for (var i = 0; i < items.length; ++i) - { - var target = items[i]; - - if (!hasClass(target.parentNode, "outline")) - continue; - - target.onclick = outlineClick; - - if (!ns_pos) - { - target.onmouseover = hoverOutline; - target.onmouseout = unhoverOutline; - } - - if (foldable(target)) - { - target.foldable = true; - target.onfocus = function () {outline = this;}; - target.onblur = function () {outline = null;}; - - if (!target.getAttribute("tabindex")) - target.setAttribute("tabindex", "0"); - - if (hasClass(target, "expand")) - unfold(target); - else - fold(target); - } - else - { - addClass(target, "nofold"); - target.visible = true; - target.foldable = false; - } - } -} - -function foldable(item) -{ - if (!item || item.nodeType != 1) - return false; - - var node = item.firstChild; - - while (node) - { - if (node.nodeType == 1 && isBlock(node)) - return true; - - node = node.nextSibling; - } - - return false; -} - -function fold(item) -{ - if (item) - { - removeClass(item, "unfolded"); - addClass(item, "folded"); - } - - var node = item ? item.firstChild : null; - - while (node) - { - if (node.nodeType == 1 && isBlock(node)) // element - { - // note that getElementStyle won't work for Safari 1.3 - node.display = getElementStyle(node, "display", "display"); - node.style.display = "none"; - node.style.visibility = "hidden"; - } - - node = node.nextSibling; - } - - item.visible = false; -} - -function unfold(item) -{ - if (item) - { - addClass(item, "unfolded"); - removeClass(item, "folded"); - } - - var node = item ? item.firstChild : null; - - while (node) - { - if (node.nodeType == 1 && isBlock(node)) // element - { - // with fallback for Safari, see above - node.style.display = (node.display ? node.display : "block"); - node.style.visibility = "visible"; - } - - node = node.nextSibling; - } - - item.visible = true; -} - -function outlineClick(e) -{ - var rightclick = false; - var target; - - if (!e) - var e = window.event; - - if (e.target) - target = e.target; - else if (e.srcElement) - target = e.srcElement; - - // work around Safari bug - if (target.nodeType == 3) - target = target.parentNode; - - while (target && target.visible == undefined) - target = target.parentNode; - - if (!target) - return true; - - if (e.which) - rightclick = (e.which == 3); - else if (e.button) - rightclick = (e.button == 2); - - if (!rightclick && target.visible != undefined) - { - if (target.foldable) - { - if (target.visible) - fold(target); - else - unfold(target); - } - - stopPropagation(e); - e.cancel = true; - e.returnValue = false; - } - - return false; -} - -function hoverOutline(e) -{ - var target; - - if (!e) - var e = window.event; - - if (e.target) - target = e.target; - else if (e.srcElement) - target = e.srcElement; - - // work around Safari bug - if (target.nodeType == 3) - target = target.parentNode; - - while (target && target.visible == undefined) - target = target.parentNode; - - if (target && target.foldable) - target.style.cursor = "pointer"; - - return true; -} - -function unhoverOutline(e) -{ - var target; - - if (!e) - var e = window.event; - - if (e.target) - target = e.target; - else if (e.srcElement) - target = e.srcElement; - - // work around Safari bug - if (target.nodeType == 3) - target = target.parentNode; - - while (target && target.visible == undefined) - target = target.parentNode; - - if (target) - target.style.cursor = "default"; - - return true; -} - - -function stopPropagation(e) -{ - if (window.event) - { - window.event.cancelBubble = true; - //window.event.returnValue = false; - } - else if (e) - { - e.cancelBubble = true; - e.stopPropagation(); - //e.preventDefault(); - } -} - -/* can't rely on display since we set that to none to hide things */ -function isBlock(elem) -{ - var tag = elem.nodeName; - - return tag == "OL" || tag == "UL" || tag == "P" || - tag == "LI" || tag == "TABLE" || tag == "PRE" || - tag == "H1" || tag == "H2" || tag == "H3" || - tag == "H4" || tag == "H5" || tag == "H6" || - tag == "BLOCKQUOTE" || tag == "ADDRESS"; -} - -function getElementStyle(elem, IEStyleProp, CSSStyleProp) -{ - if (elem.currentStyle) - { - return elem.currentStyle[IEStyleProp]; - } - else if (window.getComputedStyle) - { - var compStyle = window.getComputedStyle(elem, ""); - return compStyle.getPropertyValue(CSSStyleProp); - } - return ""; -} - -// works with text/html and text/xhtml+xml with thanks to Simon Willison -function createElement(element) -{ - if (typeof document.createElementNS != 'undefined') - { - return document.createElementNS('http://www.w3.org/1999/xhtml', element); - } - - if (typeof document.createElement != 'undefined') - { - return document.createElement(element); - } - - return false; -} - -// designed to work with both text/html and text/xhtml+xml -function getElementsByTagName(name) -{ - if (typeof document.getElementsByTagNameNS != 'undefined') - { - return document.getElementsByTagNameNS('http://www.w3.org/1999/xhtml', name); - } - - if (typeof document.getElementsByTagName != 'undefined') - { - return document.getElementsByTagName(name); - } - - return null; -} - -/* -// clean alternative to innerHTML method, but on IE6 -// it doesn't work with named entities like -// which need to be replaced by numeric entities -function insertText(element, text) -{ - try - { - element.textContent = text; // DOM3 only - } - catch (e) - { - if (element.firstChild) - { - // remove current children - while (element.firstChild) - element.removeChild(element.firstChild); - } - - element.appendChild(document.createTextNode(text)); - } -} - -// as above, but as method of all element nodes -// doesn't work in IE6 which doesn't allow you to -// add methods to the HTMLElement prototype -if (HTMLElement != undefined) -{ - HTMLElement.prototype.insertText = function(text) { - var element = this; - - try - { - element.textContent = text; // DOM3 only - } - catch (e) - { - if (element.firstChild) - { - // remove current children - while (element.firstChild) - element.removeChild(element.firstChild); - } - - element.appendChild(document.createTextNode(text)); - } - }; -} -*/ - -function getSelectedText() -{ - try - { - if (window.getSelection) - return window.getSelection().toString(); - - if (document.getSelection) - return document.getSelection().toString(); - - if (document.selection) - return document.selection.createRange().text; - } - catch (e) - { - return ""; - } - return ""; -} |