tour: map old urls to new ones where possible

Fixes golang/go#11103

Change-Id: Ib24ff2d7ae6ce46e1011c29234c02a76319bc743
Reviewed-on: https://go-review.googlesource.com/12775
Reviewed-by: Andrew Gerrand <adg@golang.org>
diff --git a/static/js/app.js b/static/js/app.js
index 9c3f5b2..7127bfc 100755
--- a/static/js/app.js
+++ b/static/js/app.js
@@ -26,6 +26,25 @@
             redirectTo: '/'
         });
 
-        $locationProvider.html5Mode(true);
+        $locationProvider.html5Mode(true).hashPrefix('!');
     }
-]);
+]).
+
+// handle mapping from old paths (#42) to the new organization.
+run(function($rootScope, $location, mapping) {
+    $rootScope.$on( "$locationChangeStart", function(event, next) {
+        var url = document.createElement('a');
+        url.href = next; 
+        if (url.pathname != '/' || url.hash == '') {
+            return;
+        }
+        $location.hash('');
+        var m = mapping[url.hash];
+        if (m === undefined) {
+            console.log('unknown url, redirecting home');
+            $location.path('/welcome/1');
+            return;
+        }
+        $location.path(m);
+    });         
+});
diff --git a/static/js/values.js b/static/js/values.js
index 7734c0d..333d05b 100644
--- a/static/js/values.js
+++ b/static/js/values.js
@@ -86,4 +86,82 @@
             if (window.codeChanged !== null) window.codeChanged();
         }
     }
+}).
+
+// mapping from the old paths (#42) to the new organization.
+// The values have been generated with the map.sh script in the tools directory.
+value('mapping', {
+    '#1': '/welcome/1', // Hello, 世界
+    '#2': '/welcome/2', // Go local
+    '#3': '/basics/1', // Packages
+    '#4': '/basics/2', // Imports
+    '#5': '/basics/3', // Exported names
+    '#6': '/basics/4', // Functions
+    '#7': '/basics/5', // Functions continued
+    '#8': '/basics/6', // Multiple results
+    '#9': undefined, // Named results
+    '#10': '/basics/8', // Variables
+    '#11': '/basics/9', // Variables with initializers
+    '#12': '/basics/10', // Short variable declarations
+    '#13': '/basics/11', // Basic types
+    '#14': '/basics/13', // Type conversions
+    '#15': '/basics/15', // Constants
+    '#16': '/basics/16', // Numeric Constants
+    '#17': '/flowcontrol/1', // For
+    '#18': '/flowcontrol/2', // For continued
+    '#19': '/flowcontrol/3', // For is Go's "while"
+    '#20': '/flowcontrol/4', // Forever
+    '#21': '/flowcontrol/5', // If
+    '#22': '/flowcontrol/6', // If with a short statement
+    '#23': '/flowcontrol/7', // If and else
+    '#24': '/flowcontrol/8', // Exercise: Loops and Functions
+    '#25': '/moretypes/2', // Structs
+    '#26': '/moretypes/3', // Struct Fields
+    '#27': '/moretypes/1', // Pointers
+    '#28': '/moretypes/5', // Struct Literals
+    '#29': undefined, // The new function
+    '#30': '/moretypes/6', // Arrays
+    '#31': '/moretypes/7', // Slices
+    '#32': '/moretypes/8', // Slicing slices
+    '#33': '/moretypes/9', // Making slices
+    '#34': '/moretypes/10', // Nil slices
+    '#35': '/moretypes/12', // Range
+    '#36': '/moretypes/13', // Range continued
+    '#37': '/moretypes/14', // Exercise: Slices
+    '#38': '/moretypes/15', // Maps
+    '#39': '/moretypes/16', // Map literals
+    '#40': '/moretypes/17', // Map literals continued
+    '#41': '/moretypes/18', // Mutating Maps
+    '#42': '/moretypes/19', // Exercise: Maps
+    '#43': '/moretypes/20', // Function values
+    '#44': '/moretypes/21', // Function closures
+    '#45': '/moretypes/22', // Exercise: Fibonacci closure
+    '#46': '/flowcontrol/9', // Switch
+    '#47': '/flowcontrol/10', // Switch evaluation order
+    '#48': '/flowcontrol/11', // Switch with no condition
+    '#49': undefined, // Advanced Exercise: Complex cube roots
+    '#50': undefined, // Methods and Interfaces
+    '#51': '/methods/1', // Methods
+    '#52': '/methods/2', // Methods continued
+    '#53': '/methods/3', // Methods with pointer receivers
+    '#54': '/methods/4', // Interfaces
+    '#55': '/methods/5', // Interfaces are satisfied implicitly
+    '#56': '/methods/8', // Errors
+    '#57': '/methods/9', // Exercise: Errors
+    '#58': '/methods/13', // Web servers
+    '#59': '/methods/14', // Exercise: HTTP Handlers
+    '#60': '/methods/15', // Images
+    '#61': '/methods/16', // Exercise: Images
+    '#62': undefined, // Exercise: Rot13 Reader
+    '#63': undefined, // Concurrency
+    '#64': '/concurrency/1', // Goroutines
+    '#65': '/concurrency/2', // Channels
+    '#66': '/concurrency/3', // Buffered Channels
+    '#67': '/concurrency/4', // Range and Close
+    '#68': '/concurrency/5', // Select
+    '#69': '/concurrency/6', // Default Selection
+    '#70': '/concurrency/7', // Exercise: Equivalent Binary Trees
+    '#71': '/concurrency/8', // Exercise: Equivalent Binary Trees
+    '#72': '/concurrency/9', // Exercise: Web Crawler
+    '#73': '/concurrency/10', // Where to Go from here...
 });
diff --git a/tools/map.sh b/tools/map.sh
new file mode 100755
index 0000000..49e3e51
--- /dev/null
+++ b/tools/map.sh
@@ -0,0 +1,41 @@
+#!/bin/sh
+
+# Copyright 2011 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 parses mapping.old and finds a correspondance from the old
+# urls (e.g. #42) to the corresponding path (e.g. /concurrency/3).
+
+function findURL {
+	title="$1"
+	file=$(grep -l "* $title\$" *.article)
+	if [[ -z $file ]]
+	then
+		echo "undefined"
+		return 1
+	fi
+	titles=$(grep "^* " $file | awk '{print NR, $0}')
+	page=$(echo "$titles" | grep "* $title\$" | awk '{print $1}')
+	if [[ $(echo "$page" | wc -l) -gt "1" ]]
+	then
+		echo "multiple matches found for $title; find 'CHOOSE BETWEEN' in the output" 1>&2
+		page="CHOOSE BETWEEN $page"
+	fi
+
+	page=$(echo $page)
+	lesson=$(echo "$file" | rev | cut -c 9- | rev)
+	echo "'/$lesson/$page'"
+	return 0
+}
+
+mapping=`cat mapping.old`
+
+pushd ../content
+echo "$mapping" | while read page; do
+	num=$(echo "$page" | awk '{print $1}')
+	title=$(echo "$page" | sed "s/[0-9]* //")
+	url=$(findURL "$title")
+	echo "    '#$num': $url, // $title"
+done
+popd > /dev/null
diff --git a/tools/mapping.old b/tools/mapping.old
new file mode 100644
index 0000000..aeb7461
--- /dev/null
+++ b/tools/mapping.old
@@ -0,0 +1,73 @@
+1 Hello, 世界
+2 Go local
+3 Packages
+4 Imports
+5 Exported names
+6 Functions
+7 Functions continued
+8 Multiple results
+9 Named results
+10 Variables
+11 Variables with initializers
+12 Short variable declarations
+13 Basic types
+14 Type conversions
+15 Constants
+16 Numeric Constants
+17 For
+18 For continued
+19 For is Go's "while"
+20 Forever
+21 If
+22 If with a short statement
+23 If and else
+24 Exercise: Loops and Functions
+25 Structs
+26 Struct Fields
+27 Pointers
+28 Struct Literals
+29 The new function
+30 Arrays
+31 Slices
+32 Slicing slices
+33 Making slices
+34 Nil slices
+35 Range
+36 Range continued
+37 Exercise: Slices
+38 Maps
+39 Map literals
+40 Map literals continued
+41 Mutating Maps
+42 Exercise: Maps
+43 Function values
+44 Function closures
+45 Exercise: Fibonacci closure
+46 Switch
+47 Switch evaluation order
+48 Switch with no condition
+49 Advanced Exercise: Complex cube roots
+50 Methods and Interfaces
+51 Methods
+52 Methods continued
+53 Methods with pointer receivers
+54 Interfaces
+55 Interfaces are satisfied implicitly
+56 Errors
+57 Exercise: Errors
+58 Web servers
+59 Exercise: HTTP Handlers
+60 Images
+61 Exercise: Images
+62 Exercise: Rot13 Reader
+63 Concurrency
+64 Goroutines
+65 Channels
+66 Buffered Channels
+67 Range and Close
+68 Select
+69 Default Selection
+70 Exercise: Equivalent Binary Trees
+71 Exercise: Equivalent Binary Trees
+72 Exercise: Web Crawler
+73 Where to Go from here...