diff --git a/i2p2www/extensions.py b/i2p2www/extensions.py
index 8442930a0cc6ac4e9f3209074583378197cb19f1..27d6f677903e5dca90d5785c8ca77ee5d046a0bb 100644
--- a/i2p2www/extensions.py
+++ b/i2p2www/extensions.py
@@ -105,13 +105,13 @@ class HighlightExtension(Extension):
 
         if ctags:
             if 'tagsfile' not in parameters:
-                parameters['tagsfile'] = module_path() + '/pages/site/spectags'
+                parameters['tagsfile'] = module_path() + '/spec/spectags'
 
             if 'tagurlformat' not in parameters:
                 lang = 'en'
                 if hasattr(g, 'lang') and g.lang:
                     lang = g.lang
-                parameters['tagurlformat'] = '/' + lang + '/%(path)s%(fname)s'
+                parameters['tagurlformat'] = '/spec/%(path)s%(fname)s'
 
         if formatter == 'textspec':
             formatter = TextSpecFormatter(**parameters)
diff --git a/i2p2www/formatters.py b/i2p2www/formatters.py
index ce4c58f8f3b9b0ddf5d264d4db877fb52609f9a5..a5987b68efec8daccc2a6b10da74ee9f0b909460 100644
--- a/i2p2www/formatters.py
+++ b/i2p2www/formatters.py
@@ -727,8 +727,8 @@ class I2PHtmlFormatter(Formatter):
                     filename, extension = os.path.splitext(filename)
                     url = self.tagurlformat % {'path': base, 'fname': filename,
                                                'fext': extension}
-                    parts[0] = "<a href=\"%s#%s_%s\">%s" % \
-                        (url, kinds[kind], value, parts[0])
+                    parts[0] = "<a href=\"%s#%s-%s\">%s" % \
+                        (url, kinds[kind], value.lower(), parts[0])
                     parts[-1] = parts[-1] + "</a>"
 
             # for all but the last line
@@ -876,7 +876,7 @@ class TextSpecFormatter(Formatter):
                     filename, extension = os.path.splitext(filename)
                     url = self.tagurlformat % {'path': base, 'fname': filename,
                                                'fext': extension}
-                    refs[value] = '\n[%s]: %s#%s_%s' % (value, url, kinds[kind], value)
+                    refs[value] = '\n[%s]: %s#%s-%s' % (value, url, kinds[kind], value.lower())
                     value = '[%s]' % value
 
             if enc:
diff --git a/i2p2www/pages/site/spectags b/i2p2www/pages/site/spectags
deleted file mode 100644
index 5033c3ba165f8b2fe6f4ad8347b02a1efc67e430..0000000000000000000000000000000000000000
--- a/i2p2www/pages/site/spectags
+++ /dev/null
@@ -1,76 +0,0 @@
-!_TAG_FILE_FORMAT	2	/extended format; --format=1 will not append ;" to lines/
-!_TAG_FILE_SORTED	1	/0=unsorted, 1=sorted, 2=foldcase/
-!_TAG_PROGRAM_AUTHOR	Darren Hiebert	/dhiebert@users.sourceforge.net/
-!_TAG_PROGRAM_NAME	Exuberant Ctags	//
-!_TAG_PROGRAM_URL	http://ctags.sourceforge.net	/official site/
-!_TAG_PROGRAM_VERSION	5.9~svn20110310	//
-BandwidthLimits	docs/spec/i2cp.html	588;"	m
-Boolean	docs/spec/common-structures.html	74;"	t
-BuildRequestRecord	docs/spec/i2np.html	183;"	s
-BuildResponseRecord	docs/spec/i2np.html	353;"	s
-Certificate	docs/spec/common-structures.html	296;"	t
-CreateLeaseSet	docs/spec/i2cp.html	630;"	m
-CreateSession	docs/spec/i2cp.html	668;"	m
-Data	docs/spec/i2np.html	1118;"	m
-DatabaseLookup	docs/spec/i2np.html	688;"	m
-DatabaseSearchReply	docs/spec/i2np.html	835;"	m
-DatabaseStore	docs/spec/i2np.html	590;"	m
-Date	docs/spec/common-structures.html	51;"	t
-DeliveryInstructions	docs/spec/common-structures.html	1010;"	s
-DeliveryStatus	docs/spec/i2np.html	910;"	m
-DestLookup	docs/spec/i2cp.html	697;"	m
-DestReply	docs/spec/i2cp.html	719;"	m
-Destination	docs/spec/common-structures.html	639;"	s
-Disconnect	docs/spec/i2cp.html	763;"	m
-Garlic	docs/spec/i2np.html	948;"	m
-GarlicClove	docs/spec/i2np.html	395;"	s
-GarlicCloveDeliveryInstructions	docs/spec/i2np.html	454;"	s
-GetBandwidthLimits	docs/spec/i2cp.html	783;"	m
-GetDate	docs/spec/i2cp.html	802;"	m
-Hash	docs/spec/common-structures.html	257;"	t
-HostLookup	docs/spec/i2cp.html	840;"	m
-HostReply	docs/spec/i2cp.html	889;"	m
-I2CPMessageHeader	docs/spec/i2cp.html	302;"	s
-I2NPMessageHeader	docs/spec/i2np.html	93;"	s
-Integer	docs/spec/common-structures.html	41;"	t
-KeysAndCert	docs/spec/common-structures.html	549;"	s
-Lease	docs/spec/common-structures.html	668;"	s
-LeaseSet	docs/spec/common-structures.html	713;"	s
-Mapping	docs/spec/common-structures.html	461;"	t
-MessageId	docs/spec/i2cp.html	324;"	s
-MessagePayload	docs/spec/i2cp.html	921;"	m
-MessageStatus	docs/spec/i2cp.html	943;"	m
-Payload	docs/spec/i2cp.html	344;"	s
-PrivateKey	docs/spec/common-structures.html	102;"	t
-PublicKey	docs/spec/common-structures.html	89;"	t
-ReceiveMessageBegin	docs/spec/i2cp.html	1048;"	m
-ReceiveMessageEnd	docs/spec/i2cp.html	1077;"	m
-ReconfigureSession	docs/spec/i2cp.html	1103;"	m
-ReportAbuse	docs/spec/i2cp.html	1133;"	m
-RequestLeaseSet	docs/spec/i2cp.html	1164;"	m
-RequestVariableLeaseSet	docs/spec/i2cp.html	1197;"	m
-RouterAddress	docs/spec/common-structures.html	843;"	s
-RouterIdentity	docs/spec/common-structures.html	613;"	s
-RouterInfo	docs/spec/common-structures.html	910;"	s
-SendMessage	docs/spec/i2cp.html	1225;"	m
-SendMessageExpires	docs/spec/i2cp.html	1272;"	m
-SessionConfig	docs/spec/i2cp.html	366;"	s
-SessionId	docs/spec/i2cp.html	398;"	s
-SessionKey	docs/spec/common-structures.html	115;"	t
-SessionStatus	docs/spec/i2cp.html	1403;"	m
-SessionTag	docs/spec/common-structures.html	269;"	t
-SetDate	docs/spec/i2cp.html	1437;"	m
-Signature	docs/spec/common-structures.html	214;"	t
-SigningPrivateKey	docs/spec/common-structures.html	171;"	t
-SigningPublicKey	docs/spec/common-structures.html	128;"	t
-String	docs/spec/common-structures.html	62;"	t
-Tunnel	docs/spec/tunnel-message.html	34;"	m
-TunnelBuild	docs/spec/i2np.html	1144;"	m
-TunnelBuildReply	docs/spec/i2np.html	1177;"	m
-TunnelData	docs/spec/i2np.html	1044;"	m
-TunnelGateway	docs/spec/i2np.html	1084;"	m
-TunnelId	docs/spec/common-structures.html	281;"	t
-TunnelMessageDeliveryInstructions	docs/spec/tunnel-message.html	159;"	s
-VariableTunnelBuild	docs/spec/i2np.html	1190;"	m
-VariableTunnelBuildReply	docs/spec/i2np.html	1220;"	m
-sampleDatagrams	docs/spec/ssu.html	1062;"	a
diff --git a/i2p2www/spec/common-structures.rst b/i2p2www/spec/common-structures.rst
index bd36dfa3932ef0ea710bf213d0cf79fe21d10845..e5c09f634f9803607a3e727cbadeed4e8079783a 100644
--- a/i2p2www/spec/common-structures.rst
+++ b/i2p2www/spec/common-structures.rst
@@ -64,7 +64,7 @@ Index
 Common type specification
 =========================
 
-.. _type-integer:
+.. _type-Integer:
 
 Integer
 -------
@@ -77,7 +77,7 @@ Contents
 ````````
 1 to 8 bytes in network byte order representing an unsigned integer
 
-.. _type-date:
+.. _type-Date:
 
 Date
 ----
@@ -91,7 +91,7 @@ Contents
 ````````
 8 byte Integer_
 
-.. _type-string:
+.. _type-String:
 
 String
 ------
@@ -107,7 +107,7 @@ in the string and the remaining 0-255 bytes are the non-null terminated UTF-8
 encoded character array.  Length limit is 255 bytes (not characters). Length
 may be 0.
 
-.. _type-boolean:
+.. _type-Boolean:
 
 Boolean
 -------
@@ -125,7 +125,7 @@ Notes
 `````
 Deprecated - unused
 
-.. _type-publickey:
+.. _type-PublicKey:
 
 PublicKey
 ---------
@@ -142,7 +142,7 @@ Contents
 
 JavaDoc: http://docs.i2p-projekt.de/javadoc/net/i2p/data/PublicKey.html
 
-.. _type-privatekey:
+.. _type-PrivateKey:
 
 PrivateKey
 ----------
@@ -159,7 +159,7 @@ Contents
 
 JavaDoc: http://docs.i2p-projekt.de/javadoc/net/i2p/data/PrivateKey.html
 
-.. _type-sessionkey:
+.. _type-SessionKey:
 
 SessionKey
 ----------
@@ -174,7 +174,7 @@ Contents
 
 JavaDoc: http://docs.i2p-projekt.de/javadoc/net/i2p/data/SessionKey.html
 
-.. _type-signingpublickey:
+.. _type-SigningPublicKey:
 
 SigningPublicKey
 ----------------
@@ -213,7 +213,7 @@ Notes
 
 JavaDoc: http://docs.i2p-projekt.de/javadoc/net/i2p/data/SigningPublicKey.html
 
-.. _type-signingprivatekey:
+.. _type-SigningPrivateKey:
 
 SigningPrivateKey
 -----------------
@@ -251,7 +251,7 @@ Notes
 
 JavaDoc: http://docs.i2p-projekt.de/javadoc/net/i2p/data/SigningPrivateKey.html
 
-.. _type-signature:
+.. _type-Signature:
 
 Signature
 ---------
@@ -290,7 +290,7 @@ Notes
 
 JavaDoc: http://docs.i2p-projekt.de/javadoc/net/i2p/data/Signature.html
 
-.. _type-hash:
+.. _type-Hash:
 
 Hash
 ----
@@ -305,7 +305,7 @@ Contents
 
 JavaDoc: http://docs.i2p-projekt.de/javadoc/net/i2p/data/Hash.html
 
-.. _type-sessiontag:
+.. _type-SessionTag:
 
 Session Tag
 -----------
@@ -320,7 +320,7 @@ Contents
 
 JavaDoc: http://docs.i2p-projekt.de/javadoc/net/i2p/data/SessionTag.html
 
-.. _type-tunnelid:
+.. _type-TunnelId:
 
 TunnelId
 --------
@@ -337,7 +337,7 @@ Contents
 
 JavaDoc: http://docs.i2p-projekt.de/javadoc/net/i2p/data/TunnelId.html
 
-.. _type-certificate:
+.. _type-Certificate:
 
 Certificate
 -----------
@@ -499,7 +499,7 @@ EdDSA_SHA512_Ed25519        96                        0
 
 JavaDoc: http://docs.i2p-projekt.de/javadoc/net/i2p/data/Certificate.html
 
-.. _type-mapping:
+.. _type-Mapping:
 
 Mapping
 -------
@@ -577,7 +577,7 @@ JavaDoc: http://docs.i2p-projekt.de/javadoc/net/i2p/data/DataHelper.html
 Common structure specification
 ==============================
 
-.. _struct-keysandcert:
+.. _struct-KeysAndCert:
 
 KeysAndCert
 -----------
@@ -648,7 +648,7 @@ Notes
 
 JavaDoc: http://docs.i2p-projekt.de/javadoc/net/i2p/data/KeysAndCert.html
 
-.. _struct-routeridentity:
+.. _struct-RouterIdentity:
 
 RouterIdentity
 --------------
@@ -677,7 +677,7 @@ Notes
 
 JavaDoc: http://docs.i2p-projekt.de/javadoc/net/i2p/data/router/RouterIdentity.html
 
-.. _struct-destination:
+.. _struct-Destination:
 
 Destination
 -----------
@@ -710,7 +710,7 @@ Notes
 
 JavaDoc: http://docs.i2p-projekt.de/javadoc/net/i2p/data/Destination.html
 
-.. _struct-lease:
+.. _struct-Lease:
 
 Lease
 -----
@@ -758,7 +758,7 @@ Notes
 
 JavaDoc: http://docs.i2p-projekt.de/javadoc/net/i2p/data/Lease.html
 
-.. _struct-leaseset:
+.. _struct-LeaseSet:
 
 LeaseSet
 --------
@@ -894,7 +894,7 @@ Notes
 
 JavaDoc: http://docs.i2p-projekt.de/javadoc/net/i2p/data/LeaseSet.html
 
-.. _struct-routeraddress:
+.. _struct-RouterAddress:
 
 RouterAddress
 -------------
@@ -966,7 +966,7 @@ Notes
 
 JavaDoc: http://docs.i2p-projekt.de/javadoc/net/i2p/data/router/RouterAddress.html
 
-.. _struct-routerinfo:
+.. _struct-RouterInfo:
 
 RouterInfo
 ----------
@@ -1067,7 +1067,7 @@ Notes
 
 JavaDoc: http://docs.i2p-projekt.de/javadoc/net/i2p/data/router/RouterInfo.html
 
-.. _struct-deliveryinstructions:
+.. _struct-DeliveryInstructions:
 
 Delivery Instructions
 ---------------------
diff --git a/i2p2www/spec/i2cp.rst b/i2p2www/spec/i2cp.rst
index 6df972666d848267836075c0a7616cf3ee5da67b..ad0f48bedfcb7e99b7a9e0b511a21434a495771b 100644
--- a/i2p2www/spec/i2cp.rst
+++ b/i2p2www/spec/i2cp.rst
@@ -296,7 +296,7 @@ below.
 Common structures
 =================
 
-.. _struct-i2cpmessageheader:
+.. _struct-I2CPMessageHeader:
 
 I2CP message header
 -------------------
@@ -316,7 +316,7 @@ Notes
 `````
 Actual message length limit is about 64 KB.
 
-.. _struct-messageid:
+.. _struct-MessageId:
 
 Message ID
 ----------
@@ -335,7 +335,7 @@ Notes
 `````
 Message IDs are unique within a session only; they are not globally unique.
 
-.. _struct-payload:
+.. _struct-Payload:
 
 Payload
 -------
@@ -355,7 +355,7 @@ Notes
 The payload is in a gzip format as specified on the I2CP Overview page
 [I2CP-FORMAT]_.
 
-.. _struct-sessionconfig:
+.. _struct-SessionConfig:
 
 Session Config
 --------------
@@ -382,7 +382,7 @@ Notes
 * The creation date must be within +/- 30 seconds of the current time when
   processed by the router, or the config will be rejected.
 
-.. _struct-sessionid:
+.. _struct-SessionId:
 
 Session ID
 ----------
@@ -438,7 +438,7 @@ SessionStatusMessage_             R -> C     20
 SetDateMessage_                   R -> C     33
 ===============================  =========  ====  =====
 
-.. _msg_bandwidthlimits:
+.. _msg-BandwidthLimits:
 
 BandwidthLimitsMessage
 ----------------------
@@ -466,7 +466,7 @@ Currently, the client limits are the only values set, and are actually the
 router limits. All the values labeled as router limits are always 0.  As of
 release 0.7.2.
 
-.. _msg-createleaseset:
+.. _msg-CreateLeaseSet:
 
 CreateLeaseSetMessage
 ---------------------
@@ -532,7 +532,7 @@ Notes
 * The [Mapping]_ in the Session Config must be sorted by key so that the
   signature will be validated correctly in the router.
 
-.. _msg-destlookup:
+.. _msg-DestLookup:
 
 DestLookupMessage
 -----------------
@@ -577,7 +577,7 @@ to the lookups.  To correlate a Destination response with a request, take the
 Hash of the Destination.  Prior to release 0.8.3, the response was empty on
 failure.
 
-.. _msg-destroysession:
+.. _msg-DestroySession:
 
 DestroySessionMessage
 ---------------------
@@ -596,7 +596,7 @@ Notes
 `````
 The router at this point should release all resources related to the session.
 
-.. _msg-disconnect:
+.. _msg-Disconnect:
 
 DisconnectMessage
 -----------------
@@ -712,7 +712,7 @@ Notes
 * Base 32 host name lookup is supported but it is preferred to convert it to a
   Hash first.
 
-.. _msg-hostreply:
+.. _msg-HostReply:
 
 HostReplyMessage
 ----------------
@@ -737,7 +737,7 @@ Notes
 * The result code is 0 for success, 1-255 for failure. Only 1 is used for
   failure now, more specific failure codes may be defined in the future.
 
-.. _msg-messagepayload:
+.. _msg-MessagePayload:
 
 MessagePayloadMessage
 ---------------------
@@ -758,7 +758,7 @@ Contents
 Notes
 `````
 
-.. _msg-messagestatus:
+.. _msg-MessageStatus:
 
 MessageStatusMessage
 --------------------
@@ -900,7 +900,7 @@ When status = 1 (accepted), the nonce matches the nonce in the
 SendMessageMessage_, and the included Message ID will be used for subsequent
 success or failure notification.  Otherwise, the nonce may be ignored.
 
-.. _msg-receivemessagebegin:
+.. _msg-ReceiveMessageBegin:
 
 ReceiveMessageBeginMessage
 --------------------------
@@ -926,7 +926,7 @@ DisconnectMessage_.
 This is unused in "fast receive" mode, which is the default as of release
 0.9.4.
 
-.. _msg-receivemessageend:
+.. _msg-ReceiveMessageEnd:
 
 ReceiveMessageEndMessage
 ------------------------
@@ -951,7 +951,7 @@ delivers a message's payload.
 This is unused in "fast receive" mode, which is the default as of release
 0.9.4.
 
-.. _msg-reconfiguresession:
+.. _msg-ReconfigureSession:
 
 ReconfigureSessionMessage
 -------------------------
@@ -981,7 +981,7 @@ Notes
   changes here will not be recognized by the router. Changes to tunnel options
   inbound.* and outbound.* are always recognized.
 
-.. _msg-reportabuse:
+.. _msg-ReportAbuse:
 
 ReportAbuseMessage
 ------------------
@@ -1009,7 +1009,7 @@ Notes
 Unused.  Not fully implemented. Both router and client can generate a
 ReportAbuseMessage_, but neither has a handler for the message when received.
 
-.. _msg-requestleaseset:
+.. _msg-RequestLeaseSet:
 
 RequestLeaseSetMessage
 ----------------------
@@ -1037,7 +1037,7 @@ This requests a [LeaseSet]_ with all [Leases]_ set to expire at the same time.
 For client versions 0.9.7 or higher, RequestVariableLeaseSetMessage_ is
 preferred.
 
-.. _msg-requestvariableleaseset:
+.. _msg-RequestVariableLeaseSet:
 
 RequestVariableLeaseSetMessage
 ------------------------------
@@ -1063,7 +1063,7 @@ This requests a [LeaseSet]_ with an individual expiration time for each
 As of release 0.9.7.  For clients before that release, use
 RequestLeaseSetMessage_.
 
-.. _msg-sendmessage:
+.. _msg-SendMessage:
 
 SendMessageMessage
 ------------------
@@ -1106,7 +1106,7 @@ to a nonzero value.  The router will not send the "accepted"
 MessageStatusMessage_ but it will later send the client a MessageStatusMessage_
 with the same nonce, and a success or failure value.
 
-.. _msg-sendmessageexpires:
+.. _msg-SendMessageExpires:
 
 SendMessageExpiresMessage
 -------------------------
@@ -1249,7 +1249,7 @@ Field value  Tags to send
    1111          160
 ===========  ============
 
-.. _msg-sessionstatus:
+.. _msg-SessionStatus:
 
 SessionStatusMessage
 --------------------
@@ -1294,7 +1294,7 @@ Status values include 0 for destroyed, 1 for created, 2 for updated, and 3 for
 invalid session.  If created, the Session ID is the identifier to be used for
 the rest of the session.
 
-.. _msg-setdate:
+.. _msg-SetDate:
 .. _SetDateMessage:
 
 Set Date
diff --git a/i2p2www/spec/i2np.rst b/i2p2www/spec/i2np.rst
index d00e6630c3591c680fc7c800f6d4c9e16eb8e9be..7303835229a9f989b53781e2b7af19bca7f7e02b 100644
--- a/i2p2www/spec/i2np.rst
+++ b/i2p2www/spec/i2np.rst
@@ -90,7 +90,7 @@ Common structures
 The following structures are elements of multiple I2NP messages.
 They are not complete messages.
 
-.. _struct-i2npmessageheader:
+.. _struct-I2NPMessageHeader:
 
 I2NP message header
 -------------------
@@ -172,7 +172,7 @@ Notes
   research to determine points in the protocol stack where the far-end router's
   version is known and checksum generation can be disabled.
 
-.. _struct-buildrequestrecord:
+.. _struct-BuildRequestRecord:
 
 BuildRequestRecord
 ------------------
@@ -346,7 +346,7 @@ Notes
 * See the tunnel creation specification [TUNNEL-CREATION]_ for details on field
   contents.
 
-.. _struct-buildresponserecord:
+.. _struct-BuildResponseRecord:
 
 BuildResponseRecord
 -------------------
@@ -391,7 +391,7 @@ Notes
 * See the tunnel creation specification [TUNNEL-CREATION]_ for details on the
   reply field.
 
-.. _struct-garlicclove:
+.. _struct-GarlicClove:
 .. _Garlic Cloves:
 
 GarlicClove
@@ -453,7 +453,7 @@ Notes
 * The Clove ID is generally set to a random number on transmit and is checked
   for duplicates on receive (same message ID space as top-level Message IDs)
 
-.. _struct-garlicclovedeliveryinstructions:
+.. _struct-GarlicCloveDeliveryInstructions:
 
 Garlic Clove Delivery Instructions
 ----------------------------------
@@ -549,7 +549,7 @@ VariableTunnelBuild_        23
 VariableTunnelBuildReply_   24
 =========================  ====
 
-.. _msg-databasestore:
+.. _msg-DatabaseStore:
 
 DatabaseStore
 -------------
@@ -650,7 +650,7 @@ Notes
 * The key is the "real" hash of the RouterIdentity or Destination, NOT the
   routing key.
 
-.. _msg-databaselookup:
+.. _msg-DatabaseLookup:
 
 DatabaseLookup
 --------------
@@ -805,7 +805,7 @@ Notes
 
 * The lookup key and exclude keys are the "real" hashes, NOT routing keys.
 
-.. _msg-databasesearchreply:
+.. _msg-DatabaseSearchReply:
 
 DatabaseSearchReply
 -------------------
@@ -879,7 +879,7 @@ Notes
 * The lookup key, peer hashes, and from hash are "real" hashes, NOT routing
   keys.
 
-.. _msg-deliverystatus:
+.. _msg-DeliveryStatus:
 
 DeliveryStatus
 --------------
@@ -922,7 +922,7 @@ Notes
   "arrival time" is set to the current network-wide ID, which is 2 (i.e.
   0x0000000000000002).
 
-.. _msg-garlic:
+.. _msg-Garlic:
 
 Garlic
 ------
@@ -1017,7 +1017,7 @@ Notes
 * In the future, the certificate could possibly be used for a HashCash to "pay"
   for the routing.
 
-.. _msg-tunneldata:
+.. _msg-TunnelData:
 
 TunnelData
 ----------
@@ -1060,7 +1060,7 @@ Notes
 
 * See also the Tunnel Message Specification [TUNNEL-MSG]_
 
-.. _msg-tunnelgateway:
+.. _msg-TunnelGateway:
 
 TunnelGateway
 -------------
@@ -1095,7 +1095,7 @@ Notes
 `````
 * The payload is an I2NP message with a standard 16-byte header.
 
-.. _msg-data:
+.. _msg-Data:
 
 Data
 ----
@@ -1124,7 +1124,7 @@ A length Integer, followed by opaque data.
        actual payload of this message
 {% endhighlight %}
 
-.. _msg_TunnelBuild:
+.. _msg-TunnelBuild:
 
 TunnelBuild
 -----------
@@ -1159,7 +1159,7 @@ Notes
 * The I2NP message ID for this message must be set according to the tunnel
   creation specification.
 
-.. _msg-tunnelbuildreply:
+.. _msg-TunnelBuildReply:
 
 TunnelBuildReply
 ----------------
@@ -1177,7 +1177,7 @@ Notes
 * The I2NP message ID for this message must be set according to the tunnel
   creation specification.
 
-.. _msg-variabletunnelbuild:
+.. _msg-VariableTunnelBuild:
 
 VariableTunnelBuild
 -------------------
@@ -1210,7 +1210,7 @@ Notes
 * The I2NP message ID for this message must be set according to the tunnel
   creation specification.
 
-msg_VariableTunnelBuildReply:
+.. _msg-VariableTunnelBuildReply:
 
 VariableTunnelBuildReply
 ------------------------
diff --git a/i2p2www/spec/spectags b/i2p2www/spec/spectags
new file mode 100644
index 0000000000000000000000000000000000000000..f1c30bc2191f26988e82b3f54c4ba2c35f57a4fc
--- /dev/null
+++ b/i2p2www/spec/spectags
@@ -0,0 +1,76 @@
+!_TAG_FILE_FORMAT	2	/extended format; --format=1 will not append ;" to lines/
+!_TAG_FILE_SORTED	1	/0=unsorted, 1=sorted, 2=foldcase/
+!_TAG_PROGRAM_AUTHOR	Darren Hiebert	/dhiebert@users.sourceforge.net/
+!_TAG_PROGRAM_NAME	Exuberant Ctags	//
+!_TAG_PROGRAM_URL	http://ctags.sourceforge.net	/official site/
+!_TAG_PROGRAM_VERSION	5.9~svn20110310	//
+BandwidthLimits	i2cp.rst	441;"	m
+Boolean	common-structures.rst	110;"	t
+BuildRequestRecord	i2np.rst	175;"	s
+BuildResponseRecord	i2np.rst	349;"	s
+Certificate	common-structures.rst	340;"	t
+CreateLeaseSet	i2cp.rst	469;"	m
+CreateSession	i2cp.rst	503;"	m
+Data	i2np.rst	1098;"	m
+DatabaseLookup	i2np.rst	653;"	m
+DatabaseSearchReply	i2np.rst	808;"	m
+DatabaseStore	i2np.rst	552;"	m
+Date	common-structures.rst	80;"	t
+DeliveryInstructions	common-structures.rst	1070;"	s
+DeliveryStatus	i2np.rst	882;"	m
+DestLookup	i2cp.rst	535;"	m
+DestReply	i2cp.rst	557;"	m
+Destination	common-structures.rst	680;"	s
+DestroySession	i2cp.rst	580;"	m
+Disconnect	i2cp.rst	599;"	m
+Garlic	i2np.rst	925;"	m
+GarlicClove	i2np.rst	394;"	s
+GarlicCloveDeliveryInstructions	i2np.rst	456;"	s
+GetBandwidthLimits	i2cp.rst	619;"	m
+GetDate	i2cp.rst	642;"	m
+Hash	common-structures.rst	293;"	t
+HostLookup	i2cp.rst	675;"	m
+HostReply	i2cp.rst	715;"	m
+I2CPMessageHeader	i2cp.rst	299;"	s
+I2NPMessageHeader	i2np.rst	93;"	s
+Integer	common-structures.rst	67;"	t
+KeysAndCert	common-structures.rst	580;"	s
+Lease	common-structures.rst	713;"	s
+LeaseSet	common-structures.rst	761;"	s
+Mapping	common-structures.rst	502;"	t
+MessageId	i2cp.rst	319;"	s
+MessagePayload	i2cp.rst	740;"	m
+MessageStatus	i2cp.rst	761;"	m
+Payload	i2cp.rst	338;"	s
+PrivateKey	common-structures.rst	145;"	t
+PublicKey	common-structures.rst	128;"	t
+ReceiveMessageBegin	i2cp.rst	903;"	m
+ReceiveMessageEnd	i2cp.rst	929;"	m
+ReconfigureSession	i2cp.rst	954;"	m
+ReportAbuse	i2cp.rst	984;"	m
+RequestLeaseSet	i2cp.rst	1012;"	m
+RequestVariableLeaseSet	i2cp.rst	1040;"	m
+RouterAddress	common-structures.rst	897;"	s
+RouterIdentity	common-structures.rst	651;"	s
+RouterInfo	common-structures.rst	969;"	s
+SendMessage	i2cp.rst	1066;"	m
+SendMessageExpires	i2cp.rst	1109;"	m
+SessionConfig	i2cp.rst	358;"	s
+SessionId	i2cp.rst	385;"	s
+SessionKey	common-structures.rst	162;"	t
+SessionStatus	i2cp.rst	1252;"	m
+SessionTag	common-structures.rst	308;"	t
+SetDate	i2cp.rst	1297;"	m
+Signature	common-structures.rst	254;"	t
+SigningPrivateKey	common-structures.rst	216;"	t
+SigningPublicKey	common-structures.rst	177;"	t
+String	common-structures.rst	94;"	t
+Tunnel	tunnel-message.rst	33;"	m
+TunnelBuild	i2np.rst	1127;"	m
+TunnelBuildReply	i2np.rst	1162;"	m
+TunnelData	i2np.rst	1020;"	m
+TunnelGateway	i2np.rst	1063;"	m
+TunnelId	common-structures.rst	323;"	t
+TunnelMessageDeliveryInstructions	tunnel-message.rst	161;"	s
+VariableTunnelBuild	i2np.rst	1180;"	m
+VariableTunnelBuildReply	i2np.rst	1213;"	m
diff --git a/i2p2www/spec/tunnel-message.rst b/i2p2www/spec/tunnel-message.rst
index 2a6fa745a48c42b210f15e6219ea35c2fdfe8bae..b41576d3083d5e29a85ca34f158f4e22426c4988 100644
--- a/i2p2www/spec/tunnel-message.rst
+++ b/i2p2www/spec/tunnel-message.rst
@@ -30,7 +30,7 @@ of attacks that are possible from observing message size.
 After the tunnel messages are created, they are encrypted as described in the
 tunnel documentation [TUNNEL-IMPL]_.
 
-.. _msg-tunnel:
+.. _msg-Tunnel:
 
 Tunnel Message (Encrypted)
 --------------------------
@@ -158,7 +158,7 @@ Notes
   IV, and take the Hash of that.
 
 
-.. _struct-tunnelmessagedeliveryinstructions:
+.. _struct-TunnelMessageDeliveryInstructions:
 
 Tunnel Message Delivery Instructions
 ====================================