From abb969b6cfe01dfe242aaff5735419383006e69c Mon Sep 17 00:00:00 2001
From: str4d <str4d@mail.i2p>
Date: Sat, 14 Nov 2015 22:25:17 +0000
Subject: [PATCH] Updated spectags

* ctags are case-sensitive, and the dataspecs use CamelCase.
* HTML anchor tags are case-sensitive. The old specs used CamelCase to match the
  ctags, and the existing documentation references them extensively.
* reStructuredText links are case-insensitive, and the HTML anchor tags that it
  generates are lower case.

Therefore, the links in the .rst files are given in CamelCase, and the dataspec
formatters convert this to lower case for links. In direct HTML references (in
specs or other areas of documentation), lower case must be used (to be fixed).

Command to generate the file:
cd i2p2www/spec && ctags -f spectags --langdef=rst --langmap=rst:.rst --regex-rst=/_type-\([a-zA-Z0-9]+\)/\\1/t,type/ --regex-rst=/_struct-\([a-zA-Z0-9]+\)/\\1/s,struct/ --regex-rst=/_msg-\([a-zA-Z]+\)/\\1/m,msg/ -R -n *.rst
---
 i2p2www/extensions.py              |  4 +-
 i2p2www/formatters.py              |  6 +--
 i2p2www/pages/site/spectags        | 76 ------------------------------
 i2p2www/spec/common-structures.rst | 46 +++++++++---------
 i2p2www/spec/i2cp.rst              | 46 +++++++++---------
 i2p2www/spec/i2np.rst              | 34 ++++++-------
 i2p2www/spec/spectags              | 76 ++++++++++++++++++++++++++++++
 i2p2www/spec/tunnel-message.rst    |  4 +-
 8 files changed, 146 insertions(+), 146 deletions(-)
 delete mode 100644 i2p2www/pages/site/spectags
 create mode 100644 i2p2www/spec/spectags

diff --git a/i2p2www/extensions.py b/i2p2www/extensions.py
index 8442930a0..27d6f6779 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 ce4c58f8f..a5987b68e 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 5033c3ba1..000000000
--- 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 bd36dfa39..e5c09f634 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 6df972666..ad0f48bed 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 d00e6630c..730383522 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 000000000..f1c30bc21
--- /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 2a6fa745a..b41576d30 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
 ====================================
-- 
GitLab