diff --git a/docs/manual/markdown/Makefile b/docs/manual/markdown/Makefile
index 48f63b2c9..4ee5d7fe9 100644
--- a/docs/manual/markdown/Makefile
+++ b/docs/manual/markdown/Makefile
@@ -1,15 +1,20 @@
 all:
 	./update_apis.py	
 	./update_listings.py
+	rm -rf docs_tmp
+	rm -rf docs_final
+	cp -r docs docs_tmp
+	cp -r docs docs_final
+	./markdown2mkdocs.py
+	rm -rf docs_tmp
 	mkdocs build --clean
-	echo "a.toctree-l4 { display: none; }" >> btstack/css/theme_extra.css
 	mkdir -p latex
 	cp -r docs/picts latex
 	cp ../picts/bklogo.pdf latex/picts
 	./markdown2pdf.py
 	cp btstack_gettingstarted.tex latex
 	cd latex && pdflatex btstack_gettingstarted.tex && pdflatex btstack_gettingstarted.tex
-	mv latex/btstack_gettingstarted.pdf btstack
+	mv latex/btstack_gettingstarted.pdf btstack.pdf
 	rm -rf latex
 
 	
diff --git a/docs/manual/markdown/btstack_gettingstarted.tex b/docs/manual/markdown/btstack_gettingstarted.tex
index 0127bb943..db9ce215c 100644
--- a/docs/manual/markdown/btstack_gettingstarted.tex
+++ b/docs/manual/markdown/btstack_gettingstarted.tex
@@ -1,6 +1,6 @@
 \documentclass[a4paper,titlepage,oneside,12pt]{amsart} %amsart
 \usepackage{graphicx}
-\usepackage{hyperref}
+\usepackage[colorlinks=true]{hyperref}
 %\usepackage{geometry} % see geometry.pdf on how to lay out the page. There's lots.
 \usepackage[margin=1.3in]{geometry}
 \geometry{a4paper} % or letter or a5paper or ... etc
@@ -147,6 +147,9 @@ morekeywords={*, timer_source_t, data_source_t, uint32_t, uint16_t, uint8_t, RUN
 \begin{document}
 
 \maketitle
+\hypersetup{linkcolor=blue}
+\hypersetup{urlcolor=blue}
+\hypersetup{citecolor=blue}
 
 \tableofcontents
 \pagebreak
diff --git a/docs/manual/markdown/docs/appendix/events_errors.md b/docs/manual/markdown/docs/appendix/events_errors.md
index b52854269..3eafa0ba3 100644
--- a/docs/manual/markdown/docs/appendix/events_errors.md
+++ b/docs/manual/markdown/docs/appendix/events_errors.md
@@ -1,6 +1,5 @@
 
-## L2CAP Events
-<a name="appendix:events_and_errors"></a>
+## L2CAP Events {#sec:eventsAndErrorsAppendix}
 
 L2CAP events and data packets are delivered to the packet handler
 specified by *l2cap_register_service* resp.
diff --git a/docs/manual/markdown/docs/architecture.md b/docs/manual/markdown/docs/architecture.md
index 9eabd4a02..537ba8e81 100644
--- a/docs/manual/markdown/docs/architecture.md
+++ b/docs/manual/markdown/docs/architecture.md
@@ -42,7 +42,7 @@ events. During a run loop cycle, the callback functions of all
 registered data sources are called. Then, the callback functions of
 timers that are ready are executed.
 
-For adapting BTstack to multi-threaded environments check [here](integration/#adapting-btstack-for-multi-threaded-environments).
+For adapting BTstack to multi-threaded environments check [here](integration/#sec:multithreadingIntegration).
 
 ## No blocking anywhere
 
diff --git a/docs/manual/markdown/docs/how_to.md b/docs/manual/markdown/docs/how_to.md
index 3098944c7..84a90ea0b 100644
--- a/docs/manual/markdown/docs/how_to.md
+++ b/docs/manual/markdown/docs/how_to.md
@@ -12,9 +12,7 @@ an overview is provided here. Finally, we describe the RFCOMM
 credit-based flow-control, which may be necessary for
 resource-constraint devices.
 
-<a name ="section:memory_configuration"></a>
-
-## Memory configuration
+## Memory configuration {#sec:memoryConfigurationHowTo}
 
 The structs for services, active connections and remote devices can be
 allocated in two different manners:
@@ -53,9 +51,8 @@ The memory is set up by calling *btstack_memory_init* function:
 
     btstack_memory_init();
 
-<a name"section:run_loop"></a>
 
-## Run loop 
+## Run loop {#sec:runLoopHowTo}
 
 BTstack uses a run loop to handle incoming data and to schedule work.
 The run loop handles events from two different types of sources: data
@@ -91,7 +88,8 @@ before its event handler callback is executed. If you need a periodic
 timer, you can re-register the same timer source in the callback
 function, as shown in Listing [PeriodicTimerHandler]. Note that BTstack
 expects to get called periodically to keep its time, see Section
-[on time abstraction](#section:test) for more on the tick hardware abstraction.
+[on time abstraction](#sec:timeAbstractionPorting) for more on the 
+tick hardware abstraction.
 
 The run loop is set up by calling *run_loop_init* function for
 embedded systems:
@@ -100,7 +98,7 @@ embedded systems:
 
     run_loop_init(RUN_LOOP_EMBEDDED);
 
-The Run loop API is provided [here](appendix/apis/#appendix:api_run_loop). To
+The Run loop API is provided [here](appendix/apis/#sec:runLoopAPIAppendix). To
 enable the use of timers, make sure that you defined HAVE_TICK in the
 config file.
 
@@ -109,12 +107,11 @@ as shown in Listing [listing:btstackInit]. The application can register
 data sources as well as timers, e.g., periodical sampling of sensors, or
 communication over the UART.
 
-<a nam="sec:btstack_initialization"></a>
 
-## BTstack initialization {#section:test}
+## BTstack initialization {#sec:btstackInitializationHowTo}
 
-To initialize BTstack you need to [initialize the memory](#section:memory_configuration)
-and [the run loop](#section:run_loop) respectively, then setup HCI and all needed higher
+To initialize BTstack you need to [initialize the memory](#sec:memoryConfigurationHowTo)
+and [the run loop](#sec:runLoopHowTo) respectively, then setup HCI and all needed higher
 level protocols.
 
 The HCI initialization has to adapt BTstack to the used platform and
@@ -146,7 +143,7 @@ requires four arguments. These are:
     [src/hci_transport_h4_dma.c]() resp. [src/hci_transport_h4_ehcill_dma.c]()
     and then getting a pointer to HCI Transport implementation.
     For more information on adapting HCI Transport to different
-    environments, see [here](porting/#hci-transport-implementation).
+    environments, see [here](porting/#sec:hciTransportPorting).
 
 <!-- -->
 
@@ -173,7 +170,7 @@ requires four arguments. These are:
     keys or remote device names. This commonly requires platform
     specific code to access the MCU’s EEPROM of Flash storage. For the
     first steps, BTstack provides a (non) persistent store in memory.
-    For more see [here](porting/#persistent-storage-api).
+    For more see [here](porting/#sec:persistentStoragePorting).
 
 <!-- -->
 
@@ -190,9 +187,8 @@ themselves with the underlying layer. In addition, the application can
 register packet handlers to get events and data as explained in the
 following section.
 
-<a name="sec:services"></a>
 
-## Services
+## Services {#sec:servicesHowTo}
 
 One important construct of BTstack is *service*. A service represents a
 server side component that handles incoming connections. So far, BTstack
@@ -204,9 +200,8 @@ ID. Outgoing connections require no special registration, they are
 created by the application when needed.
 
 
-<a name="sec:packetHandlers"></a>
 
-## Where to get data - packet handlers
+## Where to get data - packet handlers {#sec:packetHandlersHowTo}
 
 
 After the hardware and BTstack are set up, the run loop is entered. From
@@ -216,7 +211,7 @@ resulting events are delivered back to the application. Instead of
 writing a single callback handler for each possible event (as it is done
 in some other Bluetooth stacks), BTstack groups events logically and
 provides them over a single generic interface. Appendix 
-[Events and Errors](generated/appendix/#events_and_errors)
+[Events and Errors](generated/appendix/#sec:eventsAndErrorsAppendix)
 summarizes the parameters and event
 codes of L2CAP and RFCOMM events, as well as possible errors and the
 corresponding error codes.
@@ -282,9 +277,8 @@ services for the HID Control and HID Interrupt PSMs using
 a packet handler to accept and receive keyboard data.
 
 
-<a name="sec:packetlogs"></a>
 
-## Bluetooth HCI Packet Logs 
+## Bluetooth HCI Packet Logs {#sec:packetlogsHowTo}
 
 
 If things don't work as expected, having a look at the data exchanged
diff --git a/docs/manual/markdown/docs/index.md b/docs/manual/markdown/docs/index.md
index adfdea24a..0d3d4b9ec 100644
--- a/docs/manual/markdown/docs/index.md
+++ b/docs/manual/markdown/docs/index.md
@@ -8,5 +8,6 @@ protocols and profiles.
 A series of examples show how BTstack can be used to implement common 
 use cases. 
 
-Finally, we outline the basic steps when integrating BTstack into existing single-threaded or even multi-threaded environments. The changes in the documentation are listed in the [Revision History](revision_history).
+Finally, we outline the basic steps when integrating BTstack into existing 
+single-threaded or even multi-threaded environments. 
 
diff --git a/docs/manual/markdown/docs/integration.md b/docs/manual/markdown/docs/integration.md
index 8ae7dd494..a3a799f88 100644
--- a/docs/manual/markdown/docs/integration.md
+++ b/docs/manual/markdown/docs/integration.md
@@ -11,9 +11,8 @@ contains the packet handler (PH) that handles all asynchronous events
 and data packets from BTstack. The Main Application makes use of the
 Communication Logic for its Bluetooth communication.
 
-<a name="sec:singlethreading"></a> 
 
-## Adapting BTstack for Single-Threaded Environments
+## Adapting BTstack for Single-Threaded Environments {#sec:singlethreadingIntegration}
 
 
 In a single-threaded environment, all application components run on the
@@ -41,9 +40,8 @@ Currently, we have two examples for this:
     managed in a linked list. Then, the*select* function is used to wait
     for the next file descriptor to become ready or timer to expire.
 
-<a name="sec:multithreading"></a> 
 
-## Adapting BTstack for Multi-Threaded Environments
+## Adapting BTstack for Multi-Threaded Environments {#sec:multithreadingIntegration}
 
 
 The basic execution model of BTstack is a general while loop. Aside from
diff --git a/docs/manual/markdown/docs/porting.md b/docs/manual/markdown/docs/porting.md
index d7c68816f..e6ec7fad8 100644
--- a/docs/manual/markdown/docs/porting.md
+++ b/docs/manual/markdown/docs/porting.md
@@ -1,9 +1,8 @@
 In this section, we highlight the BTstack components that need to be
 adjusted for different hardware platforms.
 
-<a name="section:timeAbstraction"></a>
 
-## Time Abstraction Layer
+## Time Abstraction Layer {#sec:timeAbstractionPorting}
 
 BTstack requires a way to learn about passing time.
 *run_loop_embedded.c* supports two different modes: system ticks or a
@@ -12,7 +11,7 @@ are quite low as only Bluetooth timeouts in the second range need to be
 handled.
 
 
-### Tick Hardware Abstraction ### {#section:tickAbstraction}
+### Tick Hardware Abstraction {#sec:tickAbstractionPorting}
 
 
 If your platform doesn’t require a system clock or if you already have a
@@ -37,9 +36,8 @@ After BTstack calls *hal_tick_init()* and
 *tick_handler* gets called every
 *hal_tick_get_tick_period_in_ms()* ms.
 
-<a name="sec:timeMSAbstraction"></a>
 
-### Time MS Hardware Abstraction 
+### Time MS Hardware Abstraction {#sec:timeMSAbstractionPorting}
 
 
 If your platform already has a system clock or it is more convenient to
@@ -57,9 +55,7 @@ future. It has to return the time in milliseconds.
     uint32_t hal_time_ms(void);
 
 
-<a name="sec:bt_hw_control"></a>
-
-## Bluetooth Hardware Control API 
+## Bluetooth Hardware Control API {#sec:btHWControlPorting}
 
 
 The Bluetooth hardware control API can provide the HCI layer with a
@@ -76,9 +72,8 @@ that is not covered by the Bluetooth specification. As an example, the
 struct suitable for the CC256x chipset.
 
 
-<a name="sec:hci_transport"></a>
 
-## HCI Transport Implementation 
+## HCI Transport Implementation {#sec:hciTransportPorting}
 
 
 On embedded systems, a Bluetooth module can be connected via USB or an
@@ -87,9 +82,8 @@ commands, events and data between a host and a Bluetooth module: HCI
 UART Transport Layer (H4) and H4 with eHCILL support, a lightweight
 low-power variant by Texas Instruments.
 
-<a name="sec:hciUART"></a>
 
-### HCI UART Transport Layer (H4) 
+### HCI UART Transport Layer (H4) {#sec:hciUARTPorting}
 
 
 Most embedded UART interfaces operate on the byte level and generate a
@@ -142,9 +136,8 @@ callback for CTS interrupts.
     void hal_uart_dma_set_cts_irq_handler(void(*cts_irq_handler)(void));
     void hal_uart_dma_set_sleep(uint8_t sleep);
 
-<a name="sec:persistent_storage"></a>
 
-## Persistent Storage API 
+## Persistent Storage API {#sec:persistentStoragePorting}
 
 On embedded systems there is no generic way to persist data like link
 keys or remote device names, as every type of a device has its own
diff --git a/docs/manual/markdown/docs/profiles.md b/docs/manual/markdown/docs/profiles.md
index c699af38a..53aa0e949 100644
--- a/docs/manual/markdown/docs/profiles.md
+++ b/docs/manual/markdown/docs/profiles.md
@@ -43,10 +43,15 @@ undiscoverable again, once a connection is established. See Listing
 ### Discover remote devices {#section:DiscoverRemoteDevices}
 
 To scan for remote devices, the *hci_inquiry* command is used. Found
-remote devices are reported as a part of HCI_EVENT_INQUIRY_RESULT,
-HCI_EVENT-_INQUIRY_RESULT_WITH_RSSI, or
-HCI_EVENT_EXTENDED_INQUIRY_RESPONSE events. Each response contains
-at least the Bluetooth address, the class of device, the page scan
+remote devices are reported as a part of:
+
+- HCI_EVENT_INQUIRY_RESULT,
+
+- HCI_EVENT-_INQUIRY_RESULT_WITH_RSSI, or
+
+- HCI_EVENT_EXTENDED_INQUIRY_RESPONSE events. 
+
+Each response contains at least the Bluetooth address, the class of device, the page scan
 repetition mode, and the clock offset of found device. The latter events
 add information about the received signal strength or provide the
 Extended Inquiry Result (EIR). A code snippet is shown in Listing
@@ -104,7 +109,7 @@ device implements Bluetooth Specification 2.1 or higher, the
 *hci_write_inquiry_mode* command enables reporting of this advanced
 features (0 for standard results, 1 for RSSI, 2 for RSSI and EIR).
 
-A complete GAP inquiry example is provided [here](examples/#gapinquiry).
+A complete GAP inquiry example is provided [here](examples/generated/#sec:gapinquiryExample).
 
 ### Pairing of Devices
 
@@ -150,8 +155,8 @@ user.
 
 Regardless of the authentication mechanism (PIN/SSP), on success, both
 devices will generate a link key. The link key can be stored either in
-the Bluetooth module itself or in a persistent storage, see [here](#examples/#persistent_storage). 
-The next time the device connects and
+the Bluetooth module itself or in a persistent storage, see 
+[here](porting/#sec:persistentStoragePorting). The next time the device connects and
 requests an authenticated connection, both devices can use the
 previously generated link key. Please note that the pairing must be
 repeated if the link key is lost by one device.
@@ -177,22 +182,21 @@ for its SPP services. Section [subsection:querysdp] shows how to query
 for all RFCOMM channels. For SPP, you can do the same but use the SPP
 UUID 0x1101 for the query. After you have identified the correct RFCOMM
 channel, you can create an RFCOMM connection as shown 
-[here](protocols/#sec:rfcommlient).
+[here](protocols/#sec:rfcommClientProtocols).
 
 ### Providing an SPP Server
 
 To provide an SPP Server, you need to provide an RFCOMM service with a
 specific RFCOMM channel number as explained in section on 
-[RFCOMM service](protocols/#sec:rfcomm_service). Then, you need to create 
+[RFCOMM service](protocols/#sec:rfcommServiceProtocols). Then, you need to create 
 an SDP record for it and publish it with the SDP server by calling
 *sdp_register_service_internal*. BTstack provides the
 *sdp_create_spp_service* function in that requires an empty buffer of
 approximately 200 bytes, the service channel number, and a service name.
-Have a look at the [SPP Counter example](examples/generated/#section:sppcounter].
+Have a look at the [SPP Counter example](examples/generated/#sec:sppcounterExample].
 
-<a name="section:pan_profile"></a>
 
-## PAN - Personal Area Networking Profile 
+## PAN - Personal Area Networking Profile {#sec:panProfiles}
 
 
 The PAN profile uses BNEP to provide on-demand networking capabilities
@@ -234,7 +238,7 @@ information, you can connect BNEP to the remote PANU service with the
 
 To provide a PANU service, you need to provide a BNEP service with the
 service UUID, e.g. the PANU UUID, and a a maximal ethernet frame size,
-as explained in Section [subsubsection:bnepserver]. Then, you need to
+as explained in Section [on BNEP service](protocols/#sec:bnepServiceProtocols). Then, you need to
 create an SDP record for it and publish it with the SDP server by
 calling *sdp_register_service_internal*. BTstack provides the
 *pan_create_panu_service* function in *src/pan.c* that requires an
@@ -266,8 +270,8 @@ To toggle privacy mode using private addresses, call the
 with *gap_random_address_set_update_period*.
 
 After a connection is established, the Security Manager will try to
-resolve the peer Bluetooth address as explained in Section
-[section:smp].
+resolve the peer Bluetooth address as explained in Section on 
+[SMP](protocols/#sec:smpProtocols).
 
 ### Advertising and Discovery
 
@@ -283,8 +287,8 @@ commands can be used:
 -   *hci_le_set_advertise_enable*
 
 As these are direct HCI commands, please refer to Section
-[subsubsection:sendinghci] for details and have a look at the SPP and LE
-Counter example in Section [example:sppandlecounter].
+[subsubsection:sendinghci] for details and have a look at the [SPP and LE
+Counter example](examples/generated/#sec:sppandlecounterExample).
 
 In addition to the Advertisement data, a device in the peripheral role
 can also provide Scan Response data, which has to be explicitly queried
@@ -317,9 +321,8 @@ Services are queried and modified via ATT operations.
 GATT defines both a server and a client role. A device can implement one
 or both GATT roles.
 
-<a name = "section:GATTClient"></a>
 
-### GATT Client 
+### GATT Client {#sec:GATTClientProfiles}
 
 The GATT Client is used to discover services, and their characteristics
 and descriptors on a peer device. It can also subscribe for
@@ -347,11 +350,10 @@ perform a GATT query on a particular connection using
 completes the query.
 
 For more details on the available GATT queries, please consult 
-[GATT Client API](#appendix:api_gatt_client).
+[GATT Client API](#sec:gattClientAPIAppendix).
 
-<a name="section:GATTServer"></a>
 
-### GATT Server
+### GATT Server {#sec:GATTServerProfiles}
 
 The GATT server stores data and accepts GATT client requests, commands
 and confirmations. The GATT server sends responses to requests and when
diff --git a/docs/manual/markdown/docs/protocols.md b/docs/manual/markdown/docs/protocols.md
index d48ba21e0..c887f5330 100644
--- a/docs/manual/markdown/docs/protocols.md
+++ b/docs/manual/markdown/docs/protocols.md
@@ -137,8 +137,8 @@ and info on their parameters.
            S          Service Record (Data Element Sequence)  
   ------------------- ----------------------------------------------------
 
-### Sending HCI command based on a template 
-<a name ="sec:sendinghci"></a>
+
+### Sending HCI command based on a template {#sec:sendingHCIProtocols}
 
 You can use the *hci_send_cmd* function to send HCI command based on a
 template and a list of parameters. However, it is necessary to check
@@ -163,8 +163,9 @@ Please note, that an application rarely has to send HCI commands on its
 own. Instead, BTstack provides convenience functions in GAP and higher
 level protocols use HCI automatically.
 
-L2CAP - Logical Link Control and Adaptation Protocol
-----------------------------------------------------
+
+## L2CAP - Logical Link Control and Adaptation Protocol
+
 
 The L2CAP protocol supports higher level protocol multiplexing and
 packet fragmentation. It provides the base for the RFCOMM and BNEP
@@ -185,7 +186,7 @@ To communicate with an L2CAP service on a remote device, the application
 on a local Bluetooth device initiates the L2CAP layer using the
 *l2cap_init* function, and then creates an outgoing L2CAP channel to
 the PSM of a remote device using the *l2cap_create_channel_internal*
-function. The *l2cap_-create_channel_internal* function will initiate
+function. The *l2cap_create_channel_internal* function will initiate
 a new baseband connection if it does not already exist. The packet
 handler that is given as an input parameter of the L2CAP create channel
 function will be assigned to the new outgoing L2CAP channel. This
@@ -298,8 +299,8 @@ BTstack provides an optimized *l2cap_le* implementation in the *ble*
 folder. This L2CAP LE variant can be used for single-mode devices and
 provides the base for the ATT and SMP protocols.
 
-RFCOMM - Radio Frequency Communication Protocol
------------------------------------------------
+
+## RFCOMM - Radio Frequency Communication Protocol
 
 The Radio frequency communication (RFCOMM) protocol provides emulation
 of serial ports over the L2CAP protocol. and reassembly. It is the base
@@ -307,8 +308,8 @@ for the Serial Port Profile and other profiles used for
 telecommunication like Head-Set Profile, Hands-Free Profile, Object
 Exchange (OBEX) etc.
 
-### RFCOMM flow control. 
-<a name="sec:flowcontrol"></a>
+
+### RFCOMM flow control {#sec:flowControlProtocols}
 
 RFCOMM has a mandatory credit-based flow-control. This means that two
 devices that established RFCOMM connection, use credits to keep track of
@@ -326,24 +327,24 @@ is not much data transmitted and/or only one physical connection is
 used. If the management of credits is manual, credits are provided by
 the application such that it can manage its receive buffers explicitly.
 
-### Access an RFCOMM service on a remote device 
-<a name="sec:rfcommlient"></a>
+
+### Access an RFCOMM service on a remote device {#sec:rfcommClientProtocols}
 
 To communicate with an RFCOMM service on a remote device, the
 application on a local Bluetooth device initiates the RFCOMM layer using
 the *rfcomm_init* function, and then creates an outgoing RFCOMM channel
 to a given server channel on a remote device using the
 *rfcomm_create_channel_internal* function. The
-*rfcomm_create_channel_intern-al* function will initiate a new L2CAP
+*rfcomm_create_channel_internal* function will initiate a new L2CAP
 connection for the RFCOMM multiplexer, if it does not already exist. The
 channel will automatically provide enough credits to the remote side. To
 provide credits manually, you have to create the RFCOMM connection by
 calling *rfcomm_create_channel_with_initial_credits_internal* -
-see Section [on manual credit assignement](#sec:manualCredits).
+see Section [on manual credit assignement](#sec:manualCreditsProtocols).
 
 The packet handler that is given as an input parameter of the RFCOMM
 create channel function will be assigned to the new outgoing channel.
-This handler receives the RFCOMM_EVENT_OPEN_CHAN-NEL_COMPLETE and
+This handler receives the RFCOMM_EVENT_OPEN_CHANNEL_COMPLETE and
 RFCOMM_EVENT_CHANNEL_CLOSED events, and RFCOMM data packets, as shown in
 Listing [below](#lst:RFCOMMremoteService).
 
@@ -376,8 +377,7 @@ Listing [below](#lst:RFCOMMremoteService).
     }
 
 
-### Provide an RFCOMM service 
-<a name="sec:rfcomm_service"></a>
+### Provide an RFCOMM service {#sec:rfcommServiceProtocols}
 
 To provide an RFCOMM service, the application on a local Bluetooth
 device must first init the L2CAP and RFCOMM layers and then register the
@@ -449,8 +449,9 @@ provides the RFCOMM service example code.
         }
     }
 
-### Living with a single output buffer 
-<a name="sec:single_buffer"></a>
+
+### Living with a single output buffer {#sec:singleBufferProtocols}
+
 Outgoing packets, both commands and data, are not queued in BTstack.
 This section explains the consequences of this design decision for
 sending data and why it is not as bad as it sounds.
@@ -533,7 +534,7 @@ Listing [below](#lst:SingleOutputBufferTryPH).
 
 If the management of credits is manual, credits are provided by the
 application such that it can manage its receive buffers explicitly, see
-Listing [below].
+Listing [below](#lst:explicitFlowControl).
 
 <a name "lst:explicitFlowControl"></a>
 <!-- -->
@@ -549,7 +550,7 @@ Listing [below].
 
 
 Manual credit management is recommended when received RFCOMM data cannot
-be processed immediately. In the [SPP flow control example](examples/#sec:sppflowcontrol), 
+be processed immediately. In the [SPP flow control example](examples/generated/#sec:sppflowcontrolExample), 
 delayed processing of received data is
 simulated with the help of a periodic timer. To provide new credits, you
 call the *rfcomm_grant_credits* function with the RFCOMM channel ID
@@ -572,8 +573,8 @@ for a minimal memory footprint. If possible, multiple RFCOMM buffers
 should be used to avoid pauses while the sender has to wait for a new
 credit.
 
-### Slowing down RFCOMM data reception 
-<a name="sec:manualCredits"></a>
+
+### Slowing down RFCOMM data reception {#sec:manualCreditsProtocols}
 
 RFCOMM’s credit-based flow-control can be used to adapt, i.e., slow down
 the RFCOMM data to your processing speed. For incoming data, BTstack
@@ -595,8 +596,7 @@ connection is used. See Listing [below](#lst:automaticFlowControl).
     }
 
 
-SDP - Service Discovery Protocol
---------------------------------
+## SDP - Service Discovery Protocol
 
 The SDP protocol allows to announce services and discover services
 provided by a remote Bluetooth device.
@@ -627,11 +627,11 @@ a sub-DES. The returned pointer is used to add elements to this sub-DES.
 After adding all UUIDs, the sub-DES is “closed” with
 *de_pop_sequence*.
 
-### Query remote SDP service 
-<a name="sec:querysdp"></a>
+
+### Query remote SDP service {#sec:querySDPProtocols}
 
 BTstack provides an SDP client to query SDP services of a remote device.
-The SDP Client API is shown in [here](appendix/apis/#appendix:api_sdp). The
+The SDP Client API is shown in [here](appendix/apis/#sec:sdpAPIAppendix). The
 *sdp_client_query* function initiates an L2CAP connection to the
 remote SDP server. Upon connect, a *Service Search Attribute* request
 with a *Service Search Pattern* and a *Attribute ID List* is sent. The
@@ -735,11 +735,12 @@ of L2CAP, and it specifies a minimum L2CAP MTU of 1691 bytes.
 To receive BNEP events, please register a packet handler with
 *bnep_register_packet_handler*.
 
-### Access a BNEP service on a remote device {#subsubsection:bnepclient}
+
+### Access a BNEP service on a remote device {#sec:bnepClientProtocols}
 
 To connect to a remote BNEP service, you need to know its UUID. The set
 of available UUIDs can be queried by a SDP query for the PAN profile.
-Please see section on [PAN profile](profiles/#section:pan_profile) for details. 
+Please see section on [PAN profile](profiles/#sec:panProfiles) for details. 
 With the remote UUID, you can create a connection using the *bnep_connect* 
 function. You’ll receive a *BNEP_EVENT_OPEN_CHANNEL_COMPLETE* on success or
 failure.
@@ -756,7 +757,8 @@ multicast filters with *bnep_set_net_type_filter* and
 
 Finally, to close a BNEP connection, you can call *bnep_disconnect*.
 
-### Provide BNEP service {#subsubsection:bnepserver}
+
+### Provide BNEP service {#sec:bnepServiceProtocols}
 
 To provide a BNEP service, call *bnep_register_service* with the
 provided service UUID and a max frame size.
@@ -781,11 +783,11 @@ attribute database and provided by the *att_server* implementation. The
 constant data are automatically served by the ATT server upon client
 request. To receive the dynamic data, such is characteristic value, the
 application needs to register read and/or write callback. In addition,
-notifications and indications can be sent. Please see Section
-[section:GATTClient] for more.
+notifications and indications can be sent. Please see Section on 
+[GATT client](profiles/#sec:GATTClientProfiles) for more.
 
-## SMP - Security Manager Protocol 
-<a name="section:smp"></a>
+
+## SMP - Security Manager Protocol {#sec:smpProtocols}
 
 The SMP protocol allows to setup authenticated and encrypted LE
 connection. After initialization and configuration, SMP handles security
@@ -802,7 +804,8 @@ If you’re creating a product, you should also call *sm_set_ir()* and
 ER key seeds. If possible use a unique random number per device instead
 of deriving it from the product serial number or something similar. The
 encryption key generated by the BLE peripheral will be ultimately
-derived from the ER key seed. See [Bluetooth Specification](https://www.bluetooth.org/Technical/Specifications/adopted.htm) -
+derived from the ER key seed. See 
+[Bluetooth Specification](https://www.bluetooth.org/Technical/Specifications/adopted.htm) -
 Bluetooth Core V4.0, Vol 3, Part G, 5.2.2 for more details on deriving
 the different keys. The IR key is used to identify a device if private,
 resolvable Bluetooth addresses are used.
diff --git a/docs/manual/markdown/docs/quick_start.md b/docs/manual/markdown/docs/quick_start.md
index f6e24ccc3..a180a030d 100644
--- a/docs/manual/markdown/docs/quick_start.md
+++ b/docs/manual/markdown/docs/quick_start.md
@@ -16,7 +16,7 @@ and optionally git :
     Windows: Add Python installation folder to the Windows Path in
     Environment Variables.
 
-Adding paths to the Windows Path variable <a name="sec:windowsPath"></a>:
+### Adding paths to the Windows Path variable {#sec:windowsPathQuickStart}
 
 -   Go to: Control Panel->System->Advanced tab->Environment Variables.
 
@@ -33,7 +33,7 @@ Adding paths to the Windows Path variable <a name="sec:windowsPath"></a>:
 
 Use git to clone the latest version:
 
-            git clone https://github.com/bluekitchen/btstack.git
+    git clone https://github.com/bluekitchen/btstack.git
         
 
 Alternatively, you can download it as a ZIP archive from
@@ -54,7 +54,8 @@ provided, too.
 
 ## Run the Example
 
-As a first test, we recommend [the SPP Counter example](examples/generated/#section:sppcounter). During the startup, for TI chipsets, the init
+As a first test, we recommend the [SPP Counter example](examples/generated/#sec:sppcounterExample). 
+During the startup, for TI chipsets, the init
 script is transferred, and the Bluetooth stack brought up. After that,
 the development board is discoverable as “BTstack SPP Counter” and
 provides a single virtual serial port. When you connect to it, you’ll
@@ -83,8 +84,8 @@ Bluetooth. For this, execute:
 
 It’s also possible to run the examples on Win32 systems. For this:
 
--   Install [MSYS](www.mingw.org/wiki/msys) and
-    [MINGW32](www.mingw.org) using the MINGW installer
+-   Install [MSYS](http://www.mingw.org/wiki/msys) and
+    [MINGW32](http://www.mingw.org) using the MINGW installer
 
 -   Compile and install libusb-1.0.19 to [/usr/local/]() in msys command
     shell
@@ -113,7 +114,7 @@ and installation instructions are provided on the
 On Windows, you need to download and extract 
 [mspgcc](http://sourceforge.net/projects/mspgcc/files/Windows/mingw32/)
 to [C:\mspgcc](). Add [C:\mspgcc\bin]() folder to the Windows Path in Environment 
-variable as explained [here](#sec:windowsPath).
+variable as explained [here](#sec:windowsPathQuickStart).
 
 **Loading Firmware.** To load firmware files onto the MSP430 MCU for the
 MSP-EXP430F5438 Experimeneter board, you need a programmer like the
@@ -129,7 +130,7 @@ following software tools:
 
 <!-- -->
 
-            MSP430Flasher.exe -n MSP430F5438A -w "BINARY_FILE_NAME.hex" -v -g -z [VCC]
+    MSP430Flasher.exe -n MSP430F5438A -w "BINARY_FILE_NAME.hex" -v -g -z [VCC]
            
 
 -   [MSPDebug](http://mspdebug.sourceforge.net/):
@@ -175,9 +176,8 @@ the BLE part. The conversion script has been updated to detect
 *bluetooth_init_cc256x_1.2.bts* and adds *BLE_init_cc256x_1.2.bts*
 if present and merges them into a single .c file.
 
-<a name="platform:msp430"></a>
 
-### MSP-EXP430F5438 + CC256x Platform 
+### MSP-EXP430F5438 + CC256x Platform {#sec:platformMSP430QuickStart}
 
 **Hardware Setup.** We assume that a PAN1315, PAN1317, or PAN1323 module
 is plugged into RF1 and RF2 of the MSP-EXP430F5438 board and the “RF3
@@ -196,10 +196,11 @@ BTM805 Bluetooth module. In the port, the UART on the DAC daughter board
 was used for the debug output. Please remove the DAC board and connect a
 3.3V USB-2-UART converter to GND and TX to get the debug output.
 
-In [platforms/pic32-harmony](), a project file for the MPLAB X IDE is provided as well as a regular
+In [platforms/pic32-harmony](), a project file for the MPLAB X IDE 
+is provided as well as a regular
 Makefile. Both assume that the MPLAB XC32 compiler is installed. The
 project is set to use -Os optimization which will cause warnings if you
 only have the Free version. It will still compile a working example. For
 this platform, we only provide the SPP and LE Counter example directly.
-Other examples can be run by replacing the spp_and_le_counter.c file
+Other examples can be run by replacing the *spp_and_le_counter.c* file
 with one of the other example files.
diff --git a/docs/manual/markdown/markdown2mkdocs.py b/docs/manual/markdown/markdown2mkdocs.py
new file mode 100755
index 000000000..c3f2a47e6
--- /dev/null
+++ b/docs/manual/markdown/markdown2mkdocs.py
@@ -0,0 +1,87 @@
+#!/usr/bin/env python
+
+import sys, yaml
+import os, re
+
+def insert_anchor(mdout, reference):
+    mdout.write("<a name=\"" + reference + "\"></a>\n\n")
+
+def insert_reference(mdout, text, link):
+    mdout.write("")
+
+def fcopy(source_file, dest_file):
+    with open(dest_file, 'w') as mdout:
+        with open(source_file, 'r') as mdin:
+            for line in mdin:
+                mdout.write(line)
+
+def process_sections(temp_file, dest_file):
+    with open(dest_file, 'w') as mdout:
+        with open(temp_file, 'r') as mdin:
+            for line in mdin:
+                section = re.match('(#+.*){#(sec:.*)}',line)
+                if section:
+                    insert_anchor(mdout, section.group(2))
+                    mdout.write(section.group(1)+"\n")
+                else:
+                    mdout.write(line)
+                
+    fcopy(dest_file, temp_file)
+    return
+
+def process_figures(temp_file, dest_file):
+    with open(dest_file, 'w') as mdout:
+        with open(temp_file, 'r') as mdin:
+            for line in mdin:
+                # detect figure
+                figure = re.match('\s*(\!.*)({#(fig:.*)})',line)
+                if figure:
+                    insert_anchor(mdout, figure.group(3))
+                    mdout.write(figure.group(1)+"\n")
+                else:
+                    figure_ref = re.match('.*({@(fig:.*)})',line)
+                    if figure_ref:
+                        md_reference = "[below](#"+figure_ref.group(2)+")"
+                        line = line.replace(figure_ref.group(1), md_reference) 
+                    mdout.write(line)
+    fcopy(dest_file, temp_file)
+    return
+
+# def process_listings(temp_file, dest_file):
+#     with open(dest_file, 'w') as mdout:
+#         with open(temp_file, 'r') as mdin:
+#             for line in mdin:
+#                 mdout.write(line)
+#     fcopy(dest_file, temp_file)
+#     return
+
+# def process_tables(temp_file, dest_file):
+#     with open(dest_file, 'w') as mdout:
+#         with open(temp_file, 'r') as mdin:
+#             for line in mdin:
+#                 mdout.write(line)
+#     fcopy(dest_file, temp_file)
+#     return
+
+
+def main(argv):
+    md_template = "docs"
+    md_temp = "docs_tmp"
+    md_final = "docs_final"
+    yml_file = "mkdocs.yml"
+    
+    with open(yml_file, 'r') as yin:
+        doc = yaml.load(yin)
+        for page in doc["pages"]:
+            source_file = md_template +"/"+ page[0]
+            temp_file   = md_temp +"/"+ page[0]
+            dest_file   = md_final +"/"+ page[0]
+            
+            process_sections(temp_file, dest_file)
+            process_figures(temp_file, dest_file)
+            # process_listings(temp_file, dest_file)
+            # process_tables(temp_file, dest_file)
+
+
+if __name__ == "__main__":
+   main(sys.argv[1:])
diff --git a/docs/manual/markdown/markdown2pdf.py b/docs/manual/markdown/markdown2pdf.py
index a37cf2766..1eff3d821 100755
--- a/docs/manual/markdown/markdown2pdf.py
+++ b/docs/manual/markdown/markdown2pdf.py
@@ -24,9 +24,15 @@ def main(argv):
                 with open(docs_folder +"/"+ md_file, 'r') as mdin:
                     aout.write("\n\n#"+ title +"\n\n")
                     for line in mdin:
+                        # remove path from section reference
+                        # e.g. [the SPP Counter example](examples/generated/#sec:sppcounterExample)
+                        # replace with [the SPP Counter example](#sec:sppcounterExample)
+                        section_ref = re.match('.*\(((.*)(#sec:.*))\).*',line)
+                        if section_ref:
+                            line = line.replace(section_ref.group(2),"")
                         aout.write(line)                
 
-    pandoc_cmd = "pandoc -f markdown -t latex --listings latex/btstack_generated.md -o latex/btstack_generated.tex"
+    pandoc_cmd = "pandoc -f markdown -t latex --filter pandoc-fignos --listings latex/btstack_generated.md -o latex/btstack_generated.tex"
     p = os.popen(pandoc_cmd,"r")
     while 1:
         line = p.readline()
diff --git a/docs/manual/markdown/mkdocs.yml b/docs/manual/markdown/mkdocs.yml
index c0f218869..90b737a99 100644
--- a/docs/manual/markdown/mkdocs.yml
+++ b/docs/manual/markdown/mkdocs.yml
@@ -1,5 +1,6 @@
 site_name: BTstack Manual
 site_dir: btstack
+docs_dir: docs_final
 pages:
 - [index.md, Welcome]
 - [quick_start.md, Quick Start]
diff --git a/docs/manual/markdown/update_apis.py b/docs/manual/markdown/update_apis.py
index 22ec002d7..8f400c2ee 100755
--- a/docs/manual/markdown/update_apis.py
+++ b/docs/manual/markdown/update_apis.py
@@ -16,8 +16,7 @@ code_identation = "    "
 
 api_header = """
 
-## API_TITLE API
-<a name ="appendix:API_LABLE"></a>
+## API_TITLE API {#sec:API_LABLEAPIAppendix}
 
 """
 
@@ -26,18 +25,18 @@ api_ending = """
 
 # [file_name, api_title, api_lable]
 list_of_apis = [ 
-    [btstack_folder+"include/btstack/run_loop.h", "Run Loop", "api_run_loop"],
-    [btstack_folder+"src/hci.h", "HCI", "api_hci"],
-    [btstack_folder+"src/l2cap.h", "L2CAP", "api_l2cap"],
-    [btstack_folder+"src/rfcomm.h", "RFCOMM", "api_rfcomm"],
-    [btstack_folder+"src/sdp.h", "SDP", "api_sdp"],
-    [btstack_folder+"src/sdp_client.h", "SDP Client", "api_sdp_client"],
-    [btstack_folder+"src/sdp_query_rfcomm.h", "SDP RFCOMM Query", "api_sdp_queries"],
-    [btstack_folder+"ble/gatt_client.h", "GATT Client", "api_gatt_client"],
-    [btstack_folder+"src/pan.h", "PAN", "api_pan"],
-    [btstack_folder+"src/bnep.h", "BNEP", "api_bnep"],
-    [btstack_folder+"src/gap.h", "GAP", "api_gap"],
-    [btstack_folder+"ble/sm.h", "SM", "api_sm"]
+    [btstack_folder+"include/btstack/run_loop.h", "Run Loop", "runLoop"],
+    [btstack_folder+"src/hci.h", "HCI", "hci"],
+    [btstack_folder+"src/l2cap.h", "L2CAP", "l2cap"],
+    [btstack_folder+"src/rfcomm.h", "RFCOMM", "rfcomm"],
+    [btstack_folder+"src/sdp.h", "SDP", "sdp"],
+    [btstack_folder+"src/sdp_client.h", "SDP Client", "sdpClient"],
+    [btstack_folder+"src/sdp_query_rfcomm.h", "SDP RFCOMM Query", "sdpQueries"],
+    [btstack_folder+"ble/gatt_client.h", "GATT Client", "gattClient"],
+    [btstack_folder+"src/pan.h", "PAN", "pan"],
+    [btstack_folder+"src/bnep.h", "BNEP", "bnep"],
+    [btstack_folder+"src/gap.h", "GAP", "gap"],
+    [btstack_folder+"ble/sm.h", "SM", "sm"]
 ]
 
 def replacePlaceholder(template, title, lable):
diff --git a/docs/manual/markdown/update_listings.py b/docs/manual/markdown/update_listings.py
index bd088b9b6..ee02d9b48 100755
--- a/docs/manual/markdown/update_listings.py
+++ b/docs/manual/markdown/update_listings.py
@@ -32,12 +32,11 @@ examples_header = """
 """
 
 example_item = """
-    - [EXAMPLE_TITLE](#section:EXAMPLE_LABEL): EXAMPLE_DESC.
+    - [EXAMPLE_TITLE](#sec:EXAMPLE_LABELExample): EXAMPLE_DESC.
 """
 example_section = """
 
-## EXAMPLE_TITLE: EXAMPLE_DESC
-<a name="section:EXAMPLE_LABEL"></a>
+## EXAMPLE_TITLE: EXAMPLE_DESC {#sec:EXAMPLE_LABELExample}
 
 """
 example_subsection = """
@@ -72,7 +71,7 @@ def latexText(text, ref_prefix):
     refs = re.match('.*(Section\s+)(\w+).*',brief)
     if refs:
         brief = brief.replace(refs.group(1), "[here]")
-        brief = brief.replace(refs.group(2), "(#section:"+refs.group(2)+")")
+        brief = brief.replace(refs.group(2), "(#sec:"+refs.group(2)+")")
 
     return brief