Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

OTP-8512 Add Erlangish MarkDown to Erlangish XML support

The INSTALL.md, INSTALL-CROSS.md, and INSTALL-WIN32.md "readme files" are
now included in both the HTML and the PDF documentation.
  • Loading branch information...
commit d041cab91829ebacbd35ce2c5927f6ebe69b417a 1 parent 14801bf
@rickard-green rickard-green authored Erlang/OTP committed
View
17 .gitignore
@@ -51,6 +51,7 @@ a.out.dSYM/
/release
+/make/emd2exml
# Created by "out_build update_primary"
/bootstrap/primary_compiler/
@@ -140,6 +141,13 @@ a.out.dSYM/
/erts/doc/pdf/*.pdf
/erts/doc/man[0-9]/*.[0-9]
+# et
+
+/lib/et/doc/html/*.png
+/lib/et/doc/src/et_desc.xml
+/lib/et/doc/src/et_examples.xml
+/lib/et/doc/src/et_tutorial.xml
+
# gs
/lib/gs/src/gstk_generic.hrl
@@ -165,6 +173,7 @@ a.out.dSYM/
/lib/ic/priv/ic.jar
/lib/ic/src/icparse.erl
/lib/ic/doc/html/java
+/lib/ic/java_src/SKIP
# jinterface
@@ -234,15 +243,23 @@ a.out.dSYM/
/system/doc/pdf/*.pdf
/system/doc/pdf/*.fo
+/system/doc/html/*.html
+/system/doc/html/*.eix
+/system/doc/html/js
/system/doc/html/*/*.html
/system/doc/html/*/*.gif
/system/doc/html/*/*.eix
+/system/doc/top/PR.template
+/system/doc/top/erlresolvelinks.js
/system/doc/programming_examples/funs.xml
/system/doc/tutorial/c_port.xml
/system/doc/tutorial/c_portdriver.xml
/system/doc/tutorial/cnode.xml
/system/doc/tutorial/erl_interface.xml
/system/doc/tutorial/example.xml
+/system/doc/installation_guide/INSTALL.xml
+/system/doc/installation_guide/INSTALL-CROSS.xml
+/system/doc/installation_guide/INSTALL-WIN32.xml
# test_server
View
256 INSTALL-WIN32.md
@@ -1,18 +1,6 @@
How to Build Erlang/OTP on Windows
==================================
-Table of Contents
------------------
-
-1. Introduction
-2. Frequently Asked Questions
-3. Tools you Need and Their Environment
-4. The Shell Environment
-5. Building and Installing
-6. Development
-7. Final Words
-8. Copyright and License
-
Introduction
------------
@@ -27,7 +15,7 @@ sure of, but it certainly will...
The procedure described uses Cygwin as a build environment, you run
the bash shell in Cygwin and uses gnu make/configure/autoconf etc to
do the build. The emulator C-source code is, however, mostly compiled
-with Microsoft Visual C++(tm), producing a native Windows binary. This
+with Microsoft Visual C++, producing a native Windows binary. This
is the same procedure as we use to build the pre-built binaries. The
fact that we use VC++ and not gcc is explained further in the FAQ
section.
@@ -67,7 +55,7 @@ needed at all. Now we've used this build procedure for a couple of
releases, and it has worked fine for us. Still, there might be all
sorts of troubles on different machines and with different
setups. I'll try to give hints wherever I've encountered difficulties,
-but please share your experiences by using the [`erlang-questions`] [1]
+but please share your experiences by using the [erlang-questions] [1]
mailing list. I cannot of course help everyone with all
their problems, please try to solve the problems and submit
solutions/workarounds. Remember, it's all about sharing, not about
@@ -87,7 +75,7 @@ Frequently Asked Questions
from within the Cygwin environment. All other tools needed to build
Erlang are free-ware/open source, but not the C compiler.
-* Q: Why haven't you got rid of VC++ then, you `******`?
+* Q: Why haven't you got rid of VC++ then, you \*\*\*\*\*\*?
A: Well, partly because it's a good compiler - really! Actually it's
been possible in late R11-releases to build using mingw instead of
@@ -115,7 +103,7 @@ Frequently Asked Questions
emulation in Cygwin, which, I'm sure of, will improve, but still has
some problems. Fixing those problems might be easy or might be hard.
I suggest you try yourself and share your experience. No one would be
- happier if a simple ./configure && make would produce a fully fledged
+ happier if a simple `./configure && make` would produce a fully fledged
Cygwin binary. Ericsson does however not pay me to do a Cygwin port, so
such a port would have to happen in spare time, which is a limited
resource...
@@ -256,9 +244,9 @@ Frequently Asked Questions
$ ./otp_build boot -a
$ ./otp_build release -a
$ ./otp_build installer_win32
- $ release/win32/otp_win32_<OTP version> /S
+ $ release/win32/otp_win32_%OTP-REL% /S
- Voila! `Start->Programs->Erlang OTP <OTP version>->Erlang` starts the Erlang
+ Voila! `Start->Programs->Erlang OTP %OTP-REL%->Erlang` starts the Erlang
Windows shell.
@@ -431,7 +419,7 @@ Well' here's the list:
archives (`.a`, not `.lib`).
* Building with wxWidgets. Download wxWidgets-2.8.9 or higher patch
- release (2.9.* is a developer release which currently does not work
+ release (2.9.\* is a developer release which currently does not work
with wxErlang).
Install or unpack it to `DRIVE:/PATH/cygwin/opt/local/pgm`
@@ -448,13 +436,13 @@ Well' here's the list:
* The Erlang source distribution (from <http://www.erlang.org/download.html>).
The same as for Unix platforms. Preferably use tar from within Cygwin to
- unpack the source tar.gz (`tar zxf otp_src_R13B04.tar.gz`).
+ unpack the source tar.gz (`tar zxf otp_src_%OTP-REL%.tar.gz`).
- set the environment ERL_TOP to point to the root directory of the
+ set the environment `ERL_TOP` to point to the root directory of the
source distribution. Let's say I stood in `$HOME/src` and unpacked
- `otp_src_R13B04.tar.gz`, I then add the following to `.profile`:
+ `otp_src_%OTP-REL%.tar.gz`, I then add the following to `.profile`:
- ERL_TOP=$HOME/src/otp_src_R13B04
+ ERL_TOP=$HOME/src/otp_src_%OTP-REL%
export $ERL_TOP
* The TCL/TK binaries. You could compile Tcl/Tk for windows yourself,
@@ -546,94 +534,94 @@ Now you will have a file called `otp_win32_R12B.exe` in the
Lets get into more detail:
-`$ ./otp_build autoconf` - This step rebuilds the configure scripts to
-work correctly in the cygwin environment. In an ideal world, this
-would not be needed, but alas, we have encountered several
-incompatibilities between our distributed configure scripts (generated
-on a Linux platform) and the cygwin environment over the
-years. Running autoconf on cygwin ensures that the configure scripts
-are generated in a cygwin-compatible way and that they will work well
-in the next step.
-
-`$ ./otp_build configure` - This runs the newly generated configure scripts
-with options making configure behave nicely. The target machine type is
-plainly `win32`, so a lot of the configure-scripts recognize this
-awkward target name and behave accordingly. The CC variable also makes
-the compiler be cc.sh, which wraps MSVC++, so all configure tests
-regarding the C compiler gets to run the right compiler. A lot of the
-tests are not needed on Windows, but I thought it best to run the
-whole configure anyway. The only configure option you might want to
-supply is `--with-ssl`, which might be needed if you have built your own
-openssl distribution. The Shining Lights distribution should be found
-automatically by configure, if that fails, add a `--with-ssl=<dir>` that
-specifies the root directory of your OpenSSL installation.
-
-`$ ./otp_build boot -a` - This uses the bootstrap directory (shipped
-with the source, `$ERL_TOP/bootstrap`) to build a complete OTP
-system. It first builds an emulator and sets up a minimal OTP system
-under `$ERL_TOP/bootstrap`, then starts to compile the different OTP
-compilers to make the `$ERL_TOP/bootstrap` system potent enough to be
-able to compile all Erlang code in OTP. Then, all Erlang and C code
-under `$ERL_TOP/lib` is built using the bootstrap system, giving a
-complete OTP system (although not installed). When this is done, one
-can run Erlang from within the source tree, just type `$ERL_TOP/bin/erl`
-and you should have a prompt. If you omit the -a flag, you'll get a
-smaller system, that might be useful during development. Now
-exit from Erlang and start making a release of the thing:
-
-`$ ./otp_build release -a` - Builds a commercial release tree from the
-source tree, default is to put it in `$ERL_TOP/release/win32`, you can
-give any directory as parameter (Cygwin style), but it doesn't really matter
-if you're going to build a self extracting installer too. You could of
-course build release to the final directory and then run `./Install.exe`
-standing in the directory where the release was put, that will create
-a fully functional OTP installation. But let's make the nifty
-installer:
-
-`$ ./otp_build installer_win32` - Create the self extracting installer
-executable. The executable `otp_win32_<OTP version>.exe` will be placed
-in the top directory of the release created in the previous step. If
-no release directory is specified, the release is expected to have
-been built to `$ERL_TOP/release/win32`, which also will be the place
-where the installer executable will be placed. If you specified some
-other directory for the release (i.e.
-`./otp_build release -a /tmp/erl_release`), you're expected to give the
-same parameter here, (i.e. `./otp_build installer_win32 /tmp/erl_release`).
-You need to have a full NSIS installation and `makensis.exe` in your
-path for this to work of course. Once you have created the installer,
-you can run it to install Erlang/OTP in the regular way, just run the
-executable and follow the steps in the installation wizard. To get all
-default settings in the installation without any questions asked, you
-run the executable with the parameter `/S` (capital S). like in:
-
- $ cd $ERL_TOP
- $ release/win32/otp_win32_R13B04 /S
- ...
-
-and after a while Erlang will have been installed in
-`C:\Program Files\erl5.7.5`, with shortcuts in the menu etc.
-
-*NOTE* Beginning with R9C, the Windows installer does *not* add Erlang
-to the system wide path. If one wants to have Erlang in the path, one
-has to add it by hand.
-
-The necessary setup of an Erlang installation is actually done by the
-program `Install.exe`, which resides in the release top. That program
-creates `.ini`-files and copies the correct boot scripts. If one has
-the correct directory tree (like after a `./otp_build release -a`), only
-the running of Install.exe is necessary to get a fully functional
-OTP. What the self extracting installer adds is (of course) the
-possibility to distribute the binary easily, together with adding
-shortcuts to the Windows start menu. There is also some adding of
-entries in the registry, to associate `.erl` and `.beam` files with Erlang
-and get nifty icons, but that's not something you'll really need to
-run Erlang. The registry is also used to store uninstall information,
-but if one has not used the self extracting installer, one cannot
-(need not) do any uninstall, one just scratches the release directory
-and everything is gone. Erlang/OTP does not *need* to put anything
-in the Windows registry at all, and does not if you don't use the self
-extracting installer. In other words the installer is pure cosmetics.
-
+1. `$ ./otp_build autoconf` - This step rebuilds the configure scripts
+ to work correctly in the cygwin environment. In an ideal world, this
+ would not be needed, but alas, we have encountered several
+ incompatibilities between our distributed configure scripts (generated
+ on a Linux platform) and the cygwin environment over the
+ years. Running autoconf on cygwin ensures that the configure scripts
+ are generated in a cygwin-compatible way and that they will work well
+ in the next step.
+
+2. `$ ./otp_build configure` - This runs the newly generated configure
+ scripts with options making configure behave nicely. The target machine
+ type is plainly `win32`, so a lot of the configure-scripts recognize
+ this awkward target name and behave accordingly. The CC variable also
+ makes the compiler be `cc.sh`, which wraps MSVC++, so all configure
+ tests regarding the C compiler gets to run the right compiler. A lot of
+ the tests are not needed on Windows, but I thought it best to run the
+ whole configure anyway. The only configure option you might want to
+ supply is `--with-ssl`, which might be needed if you have built your
+ own OpenSSL distribution. The Shining Lights distribution should be
+ found automatically by `configure`, if that fails, add a
+ `--with-ssl=<dir>` that specifies the root directory of your OpenSSL
+ installation.
+
+3. `$ ./otp_build boot -a` - This uses the bootstrap directory (shipped
+ with the source, `$ERL_TOP/bootstrap`) to build a complete OTP
+ system. It first builds an emulator and sets up a minimal OTP system
+ under `$ERL_TOP/bootstrap`, then starts to compile the different OTP
+ compilers to make the `$ERL_TOP/bootstrap` system potent enough to be
+ able to compile all Erlang code in OTP. Then, all Erlang and C code
+ under `$ERL_TOP/lib` is built using the bootstrap system, giving a
+ complete OTP system (although not installed). When this is done, one
+ can run Erlang from within the source tree, just type `$ERL_TOP/bin/erl`
+ and you should have a prompt. If you omit the -a flag, you'll get a
+ smaller system, that might be useful during development. Now
+ exit from Erlang and start making a release of the thing:
+
+4. `$ ./otp_build release -a` - Builds a commercial release tree from the
+ source tree, default is to put it in `$ERL_TOP/release/win32`, you can
+ give any directory as parameter (Cygwin style), but it doesn't really
+ matter if you're going to build a self extracting installer too. You
+ could of course build release to the final directory and then run
+ `./Install.exe` standing in the directory where the release was put,
+ that will create a fully functional OTP installation. But let's make
+ the nifty installer:
+
+5. `$ ./otp_build installer_win32` - Create the self extracting installer
+ executable. The executable `otp_win32_%OTP-REL%.exe` will be placed
+ in the top directory of the release created in the previous step. If
+ no release directory is specified, the release is expected to have
+ been built to `$ERL_TOP/release/win32`, which also will be the place
+ where the installer executable will be placed. If you specified some
+ other directory for the release (i.e. `./otp_build release -a
+ /tmp/erl_release`), you're expected to give the same parameter here,
+ (i.e. `./otp_build installer_win32 /tmp/erl_release`). You need to have
+ a full NSIS installation and `makensis.exe` in your path for this to
+ work of course. Once you have created the installer, you can run it to
+ install Erlang/OTP in the regular way, just run the executable and
+ follow the steps in the installation wizard. To get all default settings
+ in the installation without any questions asked, you run the executable
+ with the parameter `/S` (capital S) like in:
+
+ $ cd $ERL_TOP
+ $ release/win32/otp_win32_%OTP-REL% /S
+ ...
+
+ and after a while Erlang/OTP-%OTP-REL% will have been installed in
+ `C:\Program Files\erl%ERTS-VSN%\`, with shortcuts in the menu etc.
+
+ The necessary setup of an Erlang installation is actually done by the
+ program `Install.exe`, which resides in the release top. That program
+ creates `.ini`-files and copies the correct boot scripts. If one has
+ the correct directory tree (like after a `./otp_build release -a`), only
+ the running of `Install.exe` is necessary to get a fully functional
+ OTP. What the self extracting installer adds is (of course) the
+ possibility to distribute the binary easily, together with adding
+ shortcuts to the Windows start menu. There is also some adding of
+ entries in the registry, to associate `.erl` and `.beam` files with
+ Erlang and get nifty icons, but that's not something you'll really need
+ to run Erlang. The registry is also used to store uninstall information,
+ but if one has not used the self extracting installer, one cannot
+ (need not) do any uninstall, one just scratches the release directory
+ and everything is gone. Erlang/OTP does not *need* to put anything
+ in the Windows registry at all, and does not if you don't use the self
+ extracting installer. In other words the installer is pure cosmetics.
+
+> *NOTE*: Beginning with R9C, the Windows installer does *not* add Erlang
+> to the system wide path. If one wants to have Erlang in the path, one
+> has to add it by hand.
Development
-----------
@@ -694,7 +682,7 @@ or even in the source directory...
$ make opt
Note that you're expected o have a fresh Erlang in your path when
-doing this, preferably the plain R13B04 you have built in the previous
+doing this, preferably the plain %OTP-REL% you have built in the previous
steps. You could also add `$ERL_TOP/bootstrap/bin` to your `PATH` before
rebuilding specific libraries, that would give you a good enough
Erlang system to compile any OTP erlang code. Setting up the path
@@ -704,7 +692,8 @@ correctly is a little bit tricky, you still need to have
in the path. A typical setting of the path for using the bootstrap
compiler would be:
- $ export PATH=$ERL_TOP/erts/etc/win32/cygwin_tools/vc:$ERL_TOP/erts/etc/win32/cygwin_tools:$ERL_TOP/bootstrap/bin:$PATH
+ $ export PATH=$ERL_TOP/erts/etc/win32/cygwin_tools/vc\
+ :$ERL_TOP/erts/etc/win32/cygwin_tools:$ERL_TOP/bootstrap/bin:$PATH
That should make it possible to rebuild any library without hassle...
@@ -760,22 +749,31 @@ Patrik, OTP
Copyright and License
---------------------
-> %CopyrightBegin%
->
-> Copyright Ericsson AB 2003-2010. All Rights Reserved.
->
-> The contents of this file are subject to the Erlang Public License,
-> Version 1.1, (the "License"); you may not use this file except in
-> compliance with the License. You should have received a copy of the
-> Erlang Public License along with this software. If not, it can be
-> retrieved online at http://www.erlang.org/.
->
-> Software distributed under the License is distributed on an "AS IS"
-> basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-> the License for the specific language governing rights and limitations
-> under the License.
->
-> %CopyrightEnd%
+%CopyrightBegin%
+
+Copyright Ericsson AB 2003-2010. All Rights Reserved.
+
+The contents of this file are subject to the Erlang Public License,
+Version 1.1, (the "License"); you may not use this file except in
+compliance with the License. You should have received a copy of the
+Erlang Public License along with this software. If not, it can be
+retrieved online at http://www.erlang.org/.
+
+Software distributed under the License is distributed on an "AS IS"
+basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+the License for the specific language governing rights and limitations
+under the License.
+
+%CopyrightEnd%
+
+Modifying This Document
+-----------------------
+
+Before modifying this document you need to have a look at the
+`$ERL_TOP/README.md.txt` document.
+
[1]: http://www.erlang.org/faq.html "mailing lists"
+
+ [?TOC]: true
View
282 INSTALL.md
@@ -1,8 +1,12 @@
Building and Installing Erlang/OTP
==================================
-Please read the whole file before attempting to build and install Erlang/OTP.
-You can find more information about Open Source Erlang/OTP at:
+Introduction
+------------
+
+This document describes how to build and install Erlang/OTP-%OTP-REL%. You
+are advised to read the whole document before attempting to build and install
+Erlang/OTP. You can find more information about Open Source Erlang/OTP at:
<http://www.erlang.org/>
@@ -10,24 +14,22 @@ The source code for Erlang/OTP can also be found in a Git repository:
<http://github.com/erlang/otp>
-Portability
------------
-
Erlang/OTP should be possible to build from source on any Unix system,
including Mac OS X. This document describes how to native compile Erlang/OTP
on Unix. For detailed instructions on how to
-* cross compile Erlang/OTP, see the [`$ERL_TOP/INSTALL-CROSS.md`] [1]
+* cross compile Erlang/OTP, see the [$ERL_TOP/INSTALL-CROSS.md][]
document.
-* build Erlang/OTP on Windows, see the [`$ERL_TOP/INSTALL-WIN32.md`] [2]
+* build Erlang/OTP on Windows, see the [$ERL_TOP/INSTALL-WIN32.md][]
document.
Binary releases for Windows can be found at
<http://www.erlang.org/download.html>.
-However, you are in any case advised to read this document first, since it
-covers building Erlang/OTP in general as well as other important information.
+Before reading the above mensioned documents you are in any case advised to
+read this document first, since it covers building Erlang/OTP in general as
+well as other important information.
Daily Build and Test
--------------------
@@ -44,9 +46,9 @@ At Ericsson we have a "Daily Build and Test" that runs on:
* x86
* SuSE Linux/GNU 10.0, 10.1
* x86
- * x86_64
+ * x86\_64
* SuSE Linux/GNU 11.0
- * x86_64
+ * x86\_64
* Gentoo Linux/GNU 1.12.11.1
* x86
* MontaVista Linux/GNU 4.0.1
@@ -60,15 +62,15 @@ At Ericsson we have a "Daily Build and Test" that runs on:
We also have the following "Daily Cross Builds":
-* SuSE Linux/GNU 10.1 x86 -> SuSE Linux/GNU 10.1 x86_64
-* SuSE Linux/GNU 10.1 x86_64 -> Linux/GNU TILEPro64
+* SuSE Linux/GNU 10.1 x86 -> SuSE Linux/GNU 10.1 x86\_64
+* SuSE Linux/GNU 10.1 x86\_64 -> Linux/GNU TILEPro64
and the following "Daily Cross Build Tests":
-* SuSE Linux/GNU 10.1 x86_64
+* SuSE Linux/GNU 10.1 x86\_64
-Versions Known *not* to Work
-----------------------------
+Versions Known NOT to Work
+--------------------------
* Suse linux 9.1 is shipped with a patched GCC version 3.3.3, having the
rpm named `gcc-3.3.3-41`. That version has a serious optimization bug
@@ -118,14 +120,15 @@ These are the tools you will need in order to unpack and build Erlang/OTP.
### Building ###
-* GNU make
-* GNU C compiler
+* GNU `make`
+* `gcc` -- GNU C compiler
* Perl 5
-* GNU m4 -- If hipe (native code) support is enabled.
-* ncurses (or termcap or termlib) -- The development headers and libraries
- are needed, often known as ncurses-devel. (Use --without-termcap to build
- without any of these libraries. Only the old shell (without any line
- editing) can be used.)
+* GNU `m4` -- If HiPE (native code) support is enabled. HiPE can be
+ disabled using `--disable-hipe`
+* `ncurses`, `termcap`, or `termlib` -- The development headers and
+ libraries are needed, often known as `ncurses-devel`. Use
+ `--without-termcap` to build without any of these libraries. Note that
+ in this case only the old shell (without any line editing) can be used.
* OpenSSL -- Optional, but needed for building the Erlang/OTP applications
`ssl` and `crypto`. You need the "development package" of OpenSSL, i.e.
including the header files. For building the application `ssl` the OpenSSL
@@ -140,23 +143,21 @@ These are the tools you will need in order to unpack and build Erlang/OTP.
* `sed` -- There seem to be some problems with some of the `sed` version on
Solaris. Make sure `/bin/sed` or `/usr/bin/sed` is used on the Solaris
platform.
-* Flex -- Optional, headers and libraries are needed to build the flex
+* `flex` -- Optional, headers and libraries are needed to build the `flex`
scanner for the `megaco` application on Unix/Linux.
-If you are building in a Git working directory you also have to have a GNU
-`autoconf` of at least version 2.59. Autoconf is however not needed if you
-build an unmodified version of the released source.
-
#### Building Documentation ####
* `xsltproc` -- XSLT processor. A tool for applying XSLT stylesheets
to XML documents. Can be downloaded from
<http://xmlsoft.org/XSLT/xsltproc2.html>.
-* `fop` -- Apache FOP print formatter (requires Java). Can be downloaded from
- <http://xmlgraphics.apache.org/fop>.
-* `Markdown.pl` -- Optional. This is a `perl` script that generates an
- HTML version of a document written in Markdown notation. Can be
- downloaded at <http://daringfireball.net/projects/markdown>.
+* `fop` -- Apache FOP print formatter (requires Java). Can be downloaded
+ from <http://xmlgraphics.apache.org/fop>.
+
+#### Building in Git ####
+
+* GNU `autoconf` of at least version 2.59. Note that `autoconf` is not
+ needed when building an unmodified version of the released source.
### Installing ###
@@ -165,12 +166,12 @@ build an unmodified version of the released source.
How to Build and Install Erlang/OTP
-----------------------------------
-The following instructions are for building using the source tar ball.
+The following instructions are for building [the released source tar ball][].
The variable `$ERL_TOP` will be mentioned a lot of times. It refers to
the top directory in the source tree. More information about `$ERL_TOP`
-can be found in the "`make` and `$ERL_TOP`" section below. If you are
-building in git you probably want to take a look at the "Building in Git"
+can be found in the [make and $ERL_TOP][] section below. If you are
+building in git you probably want to take a look at the [Building in Git][]
section below before proceeding.
### Unpacking ###
@@ -178,13 +179,16 @@ section below before proceeding.
Step 1: Start by unpacking the Erlang/OTP distribution file with your GNU
compatible TAR program.
- $ gunzip -c otp_src_R13B04.tar.gz | tar xf -
- $ zcat otp_src_R13B04.tar.gz | tar xf -
+ $ gunzip -c otp_src_%OTP-REL%.tar.gz | tar xf -
+
+alternatively:
+
+ $ zcat otp_src_%OTP-REL%.tar.gz | tar xf -
Step 2: Now cd into the base directory (`$ERL_TOP`).
- $ cd otp_src_R13B04
+ $ cd otp_src_%OTP-REL%
### Configuring ###
@@ -208,8 +212,8 @@ To instead install in `<BaseDir>/{bin,lib/erlang}`, use the
`--prefix=<BaseDir>` option.
If you upgraded the source with some patch you may need to clean up
-from previous builds before the new build. Do a `make clean`; see
-"Caveats" below.
+from previous builds before the new build. Before doing a `make clean`,
+be sure to read the [Pre-built Source Release][] section below.
### Building ###
@@ -237,46 +241,54 @@ type `./configure --help` or `./configure --help=recursive` for details.
`./configure --help=recursive` will give help for all `configure` scripts in
all applications.
-One of the things you can specify is where Erlang/OTP should be installed: by
-default Erlang/OTP will be installed in `/usr/local/{bin,lib/erlang}`;
-to keep the same structure but install in a different place, `<Dir>` say,
+One of the things you can specify is where Erlang/OTP should be installed. By
+default Erlang/OTP will be installed in `/usr/local/{bin,lib/erlang}`.
+To keep the same structure but install in a different place, `<Dir>` say,
use the `--prefix` argument like this: `./configure --prefix=<Dir>`.
Some of the available `configure` options are:
- * `--prefix=PATH`: Specify installation prefix.
- * `--{enable,disable}-threads`: Thread support (enabled by default if
+* `--prefix=PATH` - Specify installation prefix.
+* `--{enable,disable}-threads` - Thread support (enabled by default if
possible)
- * `--{enable,disable}-smp-support`: SMP support (enabled by default if
+* `--{enable,disable}-smp-support` - SMP support (enabled by default if
possible)
- * `--{enable,disable}-kernel-poll`: Kernel poll support (enabled by default
- if possible)
- * `--{enable,disable}-hipe`: HiPE support (enabled by default on supported
+* `--{enable,disable}-kernel-poll` - Kernel poll support (enabled by
+ default if possible)
+* `--{enable,disable}-hipe` - HiPE support (enabled by default on supported
platforms)
- * `--enable-darwin-universal`: Build universal binaries on darwin i386.
- * `--enable-darwin-64bit`: Build 64bit binaries on darwin
- * `--enable-m64-build`: Build 64bit binaries using the -m64 flag to (g)cc
- * `--enable-m32-build`: Build 32bit binaries using the -m32 flag to (g)cc
- * `--{with,without}-termcap`: termcap (without implies that only the old
+* `--enable-darwin-universal` - Build universal binaries on darwin i386.
+* `--enable-darwin-64bit` - Build 64-bit binaries on darwin
+* `--enable-m64-build` - Build 64-bit binaries using the `-m64` flag to
+ `(g)cc`
+* `--enable-m32-build` - Build 32-bit binaries using the `-m32` flag to
+ `(g)cc`
+* `--{with,without}-termcap` - termcap (without implies that only the old
Erlang shell can be used)
- * `--with-javac=JAVAC`: Specify Java compiler to use
- * `--{with,without}-javac`: Java compiler (without implies that the
- `jinterface` application won't be built).
- * `--{enable,disable}-dynamic-ssl-lib`: Dynamic OpenSSL libraries
- * `--{enable,disable}-shared-zlib`: Shared zlib library
- * `--with-ssl=PATH`: Specify location of OpenSSL include and lib
- * `--{with,without}-ssl`: OpenSSL (without implies that the `crypto`, `ssh`,
- and `ssl` won't be built)
-
-If you or your system has special requirements please read the
-Makefile for additional configuration information.
+* `--with-javac=JAVAC` - Specify Java compiler to use
+* `--{with,without}-javac` - Java compiler (without implies that the
+ `jinterface` application won't be built)
+* `--{enable,disable}-dynamic-ssl-lib` - Dynamic OpenSSL libraries
+* `--{enable,disable}-shared-zlib` - Shared zlib library
+* `--with-ssl=PATH` - Specify location of OpenSSL include and lib
+* `--{with,without}-ssl` - OpenSSL (without implies that the `crypto`,
+ `ssh`, and `ssl` won't be built)
+
+If you or your system has special requirements please read the `Makefile` for
+additional configuration information.
#### Building ####
Step 5 builds the Erlang/OTP system. On a fast computer, this will take about
5 minutes. After completion of this step, you should have a working
Erlang/OTP system which you can try by typing `bin/erl`. This should start
-up Erlang/OTP and give you a prompt.
+up Erlang/OTP and give you a prompt:
+
+ $ bin/erl
+ Erlang %OTP-REL% (erts-%ERTS-VSN%) [source] [smp:4:4] [rq:4] [async-threads:0] [kernel-poll:false]
+
+ Eshell V%ERTS-VSN% (abort with ^G)
+ 1> _
#### Installing ####
@@ -286,7 +298,7 @@ without having to do step 5 again).
##### Alternative Installation Procedures #####
-* Staged install using [`DESTDIR`] [3]. You can perform the install
+* Staged install using [DESTDIR][]. You can perform the install
phase in a temporary directory and later move the installation into
its correct location by use of the `DESTDIR` variable:
@@ -366,7 +378,7 @@ without having to do step 5 again).
if you want to try the system out, running test suites, etc, before doing
the real install without `EXTRA_PREFIX`.
-### Symbolic Links in `--bindir` ###
+### Symbolic Links in --bindir ###
When doing `make install` and the default installation prefix is used,
relative symbolic links will be created from `/usr/local/bin` to all public
@@ -380,6 +392,24 @@ passed to `configure`. One can force relative, or absolute links by passing
phase. Note that such a request might cause a failure if the request cannot
be satisfied.
+### Pre-built Source Release ###
+
+The source release is delivered with a lot of platform independent
+build results already pre-built. If you want to remove these pre-built
+files, invoke `./otp_build remove_prebuilt_files` from the `$ERL_TOP`
+directory. After you have done this, you can build exactly the same way
+as before, but the build process will take a much longer time.
+
+> *WARNING*: Doing `make clean` in an arbitrary directory of the source
+> tree, may remove files needed for bootstrapping the build.
+>
+> Doing `./otp_build save_bootstrap` from the `$ERL_TOP` directory before
+> doing `make clean` will ensure that it will be possible to build after
+> doing `make clean`. `./otp_build save_bootstrap` will be invoked
+> automatically when `make` is invoked from `$ERL_TOP` with either the
+> `clean` target, or the default target. It is also automatically invoked
+> if `./otp_build remove_prebuilt_files` is invoked.
+
### Building in Git ###
When building in a Git working directory you also have to have a GNU `autoconf`
@@ -394,32 +424,13 @@ content, and you may therefore have to regenerate the `configure` scripts
when checking out a branch. Regenerated `configure` scripts imply that you
have to run `configure` and build again.
-Note that running `./otp_build autoconf` is **not** needed when building an
-unmodified version the released source.
+> *NOTE*: Running `./otp_build autoconf` is **not** needed when building
+> an unmodified version the released source.
Other useful information can be found at our github wiki:
<http://wiki.github.com/erlang/otp>
-Pre-built Source Tree
----------------------
-
-The source tree is delivered with a lot of platform independent
-build results already pre-built. If you want to remove these pre-built
-files, invoke `./otp_build remove_prebuilt_files` from the `$ERL_TOP`
-directory. After you have done this, you can build exactly the same way
-as before, but the build process will take a much longer time.
-
-*NOTE*: Doing `make clean` in an arbitrary directory of the source tree,
-may remove files needed for bootstrapping the build. Doing
-`./otp_build save_bootstrap` from the `$ERL_TOP` directory before
-doing `make clean` will ensure that it will be possible to build after
-doing `make clean`. `./otp_build save_bootstrap` will be invoked
-automatically when `make` is invoked from `$ERL_TOP` with either the
-`clean` target, or the default target. It is also automatically invoked
-if `./otp_build remove_prebuilt_files` is invoked.
-
-`make` and `$ERL_TOP`
----------------------
+### make and $ERL\_TOP ###
All the makefiles in the entire directory tree use the environment
variable `ERL_TOP` to find the absolute path of the installation. The
@@ -437,8 +448,10 @@ want to rebuild the application `STDLIB`, then you could do:
where `<Dir>` would be what you find `ERL_TOP` is set to in the top level
Makefile.
-How to Build the Erlang/OTP Documentation
------------------------------------------
+The Erlang/OTP Documentation
+----------------------------
+
+### How to Build the Documentation ###
$ cd $ERL_TOP
@@ -448,19 +461,10 @@ already ran `configure` and do not need to do this again; otherwise, run
$ ./configure [Configure Args]
-When building the documentation you need a full Erlang/OTP-R13B04 system in
+When building the documentation you need a full Erlang/OTP-%OTP-REL% system in
the `$PATH`.
- $ export PATH=<Erlang/OTP-R13B04 bin dir>:$PATH # Assuming bash/sh
-
-This document as well as some other documents have been written using
-Markdown notation. HTML versions of these documents are created and included
-in the HTML documentation if the environment variable `MD2HTML` is set to a
-command that generates HTML on `stdout` for a Markdown document passed as
-argument. This is a last minute hack, which will be handled in a better way
-in the future. We currently set `MD2HTML` as follows.
-
- $ export MD2HTML="perl <path to script>/Markdown.pl --html4tags"
+ $ export PATH=<Erlang/OTP-%OTP-REL% bin dir>:$PATH # Assuming bash/sh
Build the documentation.
@@ -478,13 +482,13 @@ or using the `release_docs` target.
* If you have installed Erlang/OTP using the `release` target, install
the documentation using the `release_docs` target. You typically want
- to use the same RELEASE_ROOT as when invoking `make release`.
+ to use the same `RELEASE_ROOT` as when invoking `make release`.
$ make release_docs RELEASE_ROOT=<release dir>
-### Build Issues ###
+#### Build Issues ####
-We have sometimes experienced problems with suns `java` running out of
+We have sometimes experienced problems with Sun's `java` running out of
memory when running `fop`. Increasing the amount of memory available
as follows has in our case solved the problem.
@@ -493,23 +497,22 @@ as follows has in our case solved the problem.
More information can be found at
<http://xmlgraphics.apache.org/fop/0.95/running.html#memory>.
-How to Install the Pre-formatted Erlang/OTP Documentation
----------------------------------------------------------
+### How to Install the Pre-formatted Documentation ###
-Pre-formatted documentation can be downloaded at
+Pre-formatted [html documentation][] and [man pages][] can be downloaded at
<http://www.erlang.org/download.html>.
For some graphical tools to find the on-line help you have to install
the HTML documentation on top of the installed OTP applications, i.e.
$ cd <ReleaseDir>
- $ gunzip -c otp_html_R13B04.tar.gz | tar xf -
+ $ gunzip -c otp_html_%OTP-REL%.tar.gz | tar xf -
For `erl -man <page>` to work the Unix manual pages have to be
installed in the same way, i.e.
$ cd <ReleaseDir>
- $ gunzip -c otp_man_R13B04.tar.gz | tar xf -
+ $ gunzip -c otp_man_%OTP-REL%.tar.gz | tar xf -
Where `<ReleaseDir>` is
@@ -620,7 +623,7 @@ To add hipe options, write like this from the Erlang shell:
1> c(Module, [native,{hipe,HipeOptions}|MoreOptions]).
-Use hipe:help_options/0 to print out the available options.
+Use `hipe:help_options/0` to print out the available options.
1> hipe:help_options().
@@ -702,6 +705,7 @@ purposes.
Authors
-------
+
Authors are mostly listed in the application's `AUTHORS` files,
that is `$ERL_TOP/lib/*/AUTHORS` and `$ERL_TOP/erts/AUTHORS`,
not in the individual source files.
@@ -709,30 +713,44 @@ not in the individual source files.
Copyright and License
---------------------
-> %CopyrightBegin%
->
-> Copyright Ericsson AB 1998-2010. All Rights Reserved.
->
-> The contents of this file are subject to the Erlang Public License,
-> Version 1.1, (the "License"); you may not use this file except in
-> compliance with the License. You should have received a copy of the
-> Erlang Public License along with this software. If not, it can be
-> retrieved online at http://www.erlang.org/.
->
-> Software distributed under the License is distributed on an "AS IS"
-> basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-> the License for the specific language governing rights and limitations
-> under the License.
->
-> %CopyrightEnd%
+%CopyrightBegin%
+
+Copyright Ericsson AB 1998-2010. All Rights Reserved.
+
+The contents of this file are subject to the Erlang Public License,
+Version 1.1, (the "License"); you may not use this file except in
+compliance with the License. You should have received a copy of the
+Erlang Public License along with this software. If not, it can be
+retrieved online at http://www.erlang.org/.
+
+Software distributed under the License is distributed on an "AS IS"
+basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+the License for the specific language governing rights and limitations
+under the License.
+
+%CopyrightEnd%
More Information
----------------
More information can be found at <http://www.erlang.org>.
+Modifying This Document
+-----------------------
+
+Before modifying this document you need to have a look at the
+`$ERL_TOP/README.md.txt` document.
+
+
+ [$ERL_TOP/INSTALL-CROSS.md]: INSTALL-CROSS
+ [$ERL_TOP/INSTALL-WIN32.md]: INSTALL-WIN32
+ [DESTDIR]: http://www.gnu.org/prep/standards/html_node/DESTDIR.html
+ [Building in Git]: #How-to-Build-and-Install-ErlangOTP_Building-in-Git
+ [Pre-built Source Release]: #How-to-Build-and-Install-ErlangOTP_Prebuilt-Source-Release
+ [make and $ERL_TOP]: #How-to-Build-and-Install-ErlangOTP_make-and-ERLTOP
+ [html documentation]: http://www.erlang.org/download/otp_doc_html_%OTP-REL%.tar.gz
+ [man pages]: http://www.erlang.org/download/otp_doc_man_%OTP-REL%.tar.gz
+ [the released source tar ball]: http://www.erlang.org/download/otp_src_%OTP-REL%.tar.gz
- [1]: INSTALL-CROSS.html "$ERL_TOP/INSTALL-CROSS.md"
- [2]: INSTALL-WIN32.html "$ERL_TOP/INSTALL-WIN32.md"
- [3]: http://www.gnu.org/prep/standards/html_node/DESTDIR.html "DESTDIR"
+ [?TOC]: true
View
43 Makefile.in
@@ -28,10 +28,10 @@ SHELL = /bin/sh
ERL_TOP = @ERL_TOP@
# OTP release
-OTP = @OTP@
+OTP = OTP-@OTP_REL@
# erts (Erlang RunTime System) version
-ERTS = @ERTS@
+ERTS = erts-@ERTS_VSN@
# ----------------------------------------------------------------------
@@ -397,7 +397,7 @@ endif
# ---------------------------------------------------------------
# Target only used when building commercial ERTS patches
# ---------------------------------------------------------------
-release_docs docs: html_readmes
+release_docs docs:
ifeq ($(OTP_SMALL_BUILD),true)
cd $(ERL_TOP)/lib && \
ERL_TOP=$(ERL_TOP) $(MAKE) TESTROOT=$(RELEASE_ROOT) $@
@@ -412,41 +412,6 @@ endif
cd $(ERL_TOP)/system/doc && \
ERL_TOP=$(ERL_TOP) $(MAKE) TESTROOT=$(RELEASE_ROOT) $@
-.PHONY: html_readmes clean_html_readmes
-
-HTML_READMES = INSTALL.html INSTALL-WIN32.html INSTALL-CROSS.html
-
-html_readmes: $(HTML_READMES)
-
-clean_html_readmes:
- rm -f $(HTML_READMES)
-
-%.html: %.md
- echo "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">" > $@
- echo "<html xmlns:fn=\"http://www.w3.org/2005/02/xpath-functions\"><head>" >> $@
- echo "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">" >> $@
- echo "<style type=\"text/css\">" >> $@
- echo "body {" >> $@
- echo " margin: 4em 4em 4em 4em;" >> $@
- echo " background: white;" >> $@
- echo " font-family: Verdana, Arial, Helvetica, sans-serif;" >> $@
- echo "}" >> $@
- echo "code { font-family: courier;font-weight: normal}" >> $@
- echo "a:link { color: blue; text-decoration: none }" >> $@
- echo "a:active { color: blue; text-decoration: none }" >> $@
- echo "a:visited { color: blue; text-decoration: none }" >> $@
- echo "</style><title>" >> $@
- cat $< | sed -n "s/[ ]*\([^ ].*[^ ]\)[ ]*/\1/p;/[ ]*[^ ][ ]*/q" >> $@
- echo "</title></head><body>" >> $@
-ifneq ($(MD2HTML),)
- $(MD2HTML) $< >> $@
-else
- echo "<pre>" >> $@
- cat $< | sed "s|\&|\&amp\;|g;s|\"|\&quot\;|g;s|<|\&lt\;|g;s|>|\&gt\;|g" >> $@
- echo "</pre>" >> $@
-endif
- echo "</body></html>" >> $@
-
# ----------------------------------------------------------------------
ERLANG_EARS=$(BOOTSTRAP_ROOT)/bootstrap/erts
ELINK=$(BOOTSTRAP_ROOT)/bootstrap/erts/bin/elink
@@ -1032,7 +997,7 @@ $(IBIN_DIR):
# Clean targets
#
-clean: check_recreate_primary_bootstrap clean_html_readmes
+clean: check_recreate_primary_bootstrap
rm -f *~ *.bak config.log config.status prebuilt.files ibin/*
find . -type f -name SKIP -print | xargs $(RM)
cd erts && ERL_TOP=$(ERL_TOP) $(MAKE) clean
View
266 README.md.txt
@@ -0,0 +1,266 @@
+Erlangish Markdown Text Files
+=============================
+
+Introduction
+------------
+
+If you are looking for information on how to build and install Erlang/OTP you
+want to read the [$ERL_TOP/INSTALL.md][] document instead of this document
+(where `$ERL_TOP` is the top source directory in the source tree).
+
+All files with the `.md` suffix (as well as this file) are ordinary text files
+written using a Markdown like notation, and can be read using an ordinary text
+editor such as for example `emacs`.
+
+This document describes how `*.md` files in the Erlang/OTP source tree should
+be written.
+
+> *NOTE*: Before modifying a `*.md` file read all of this document.
+
+Erlangish Markdown
+------------------
+
+We do not use Markdown straight out of the box. The Markdown syntax we use is
+similar to the original Markdown but with a number of tweaks. The original
+Markdown is documented at <http://daringfireball.net/projects/markdown/>. You
+should read that documentation as well as this document before modifying any
+Erlangish Markdown files in the Erlang/OTP source tree.
+
+The original Markdown syntax was designed for generating HTML code from an
+"easy to read/easy to write" plain text. Instead of generating HTML we generate
+XML that fits into our documentation, i.e. we generate Erlangish XML from
+Erlangish Markdown.
+
+The `.md` suffix has been chosen since [github][] will generate HTML pages for
+files with the `.md` suffix. Github does however not generate HTML according to
+Erlangish Markdown, so some features do not work. The Erlangish Markdown
+documents viewed at [our github repository][] will typically suffer from broken
+links. The original Markdown script, gitub's Markdown, and our Erlangish
+Markdown script will generate somewhat different results if you do not follow
+indentation rules outlined in the Markdown documentation. You are encouraged to
+try to write using a Markdown syntax that also looks nice on github. However,
+it is *much* more important that the document is formatted correct in the
+Erlang/OTP documentation.
+
+### Differences Between Markdown and Erlangish Markdown ###
+
+#### Missing Features ####
+
+This functionality is missing compared to Markdown version 1.0.1. Do not
+depend on the fact that these features are missing. Some of them might appear
+in the future.
+
+* No inline HTML. Currently no inline XML is allowed either. Inline XML might
+ be allowed in the future, but there is no real need for it since we use
+ Erlangish Markdown for "readme"s that have a main purpose of being readable
+ in plain text.
+
+* Backslash escapes all characters.
+
+* No support for "horizontal rules".
+
+* Links.
+ * No support for the "title" attribute.
+ * Automatic links does not support email addresses.
+
+* Images.
+ * No support for the "title" attribute. Specified "title" will however
+ be used as `<icaption>`.
+ * No support for the "alt" attribute.
+
+* Lists aren't supported inside block quotes.
+
+* Link and image definition names *are* case sensitive.
+
+#### Additional Features ####
+
+* Automatic anchors at each heading.
+
+* Optionally automatically generated table of contents.
+
+* Note blocks.
+
+* Warning blocks.
+
+#### Extra requirements ####
+
+* One and only one level 1 heading is allowed and required.
+
+* The level 1 heading must be the first heading in the document.
+
+* A level `X` heading must have a level `X-1` heading as parent heading.
+
+* Link and image definition names aren't allowed to begin with a
+ question mark (?) character. Names beginning with a question mark have
+ been reserved for other use.
+
+* The encoding of the file containing Erlangish Markdown should be
+ UTF-8.
+
+### Generated XML ###
+
+> *WARNING*: The `emd2exml` script will blindly generate XML code according
+> to the Erlangish Markdown in a file. Successfully generated XML does **not**
+> imply that the generated XML adheres to used DTDs. `emd2exml` does very
+> seldom fail and can easily generate XML that will cause the documentation
+> build to fail. You always have to keep in mind that the XML generated
+> should fit the chapter DTD of Erlang/OTP. Also note that even though HTML
+> generation succeeds the PDF generation might fail, etc.
+>
+> *Always build the Erlang/OTP documentation after modifying an Erlangish
+> Markdown document!*
+
+A note about how we talk about "tags" below. When we say "generate(s) `<X>`
+tags" this also imply that ending `</X>` tags will be generated at appropriate
+places. Appropriate attributes to the `X` tag will also be generated.
+
+* Inline and reference style links will either generate `<seealso>` tags
+ or `<url>` tags. If a "://" character sequence is found in the URL an
+ `<url>` tag will be generated; otherwise, a `<seealso>` tag is generated.
+
+* Automatic links will only generate `<url>` tags. This since a
+ "://" character sequence have to be present in the URL in order
+ for the link to be identified.
+
+* Inline and reference style images will generate a `<image file="...">
+ <icaption>...</icaption> </image>` sequence where the "title" will be
+ placed between `<icaption>` and `</icaption>`.
+
+* Block quotes generate `<blockquote>` tags.
+
+* If the first line of a top level block quote begins with a `> *NOTE*:`
+ character sequence, a `<note>` tag will be generated instead of a
+ `<blockquote>` tag. The note will span the entire block quote.
+
+* If the first line of a top level block quote begins with a `> *WARNING*:`
+ character sequence, a `<warning>` tag will be generated instead of a
+ `<blockquote>` tag. The warning will span the entire block quote.
+
+* Paragraphs will generate `<p>` tags.
+
+* Break line (double trailing white space) will generate `<br/>` tags.
+
+* An unordered list generates a `<list type="bulleted">` tag and `<item>`
+ tags for each item.
+
+* An ordered list generates a `<list type="ordered">` tag and `<item>` tags
+ for each item.
+
+* Code blocks will generate `<code type="none">` tags.
+
+* Code span (backticks) will generate `<c>` tags.
+
+* Emphasis (single `*` or `_`) will generate `<em>` tags.
+
+* Strong emphasis (double `*` or `_`) will generate `<b>` tags.
+
+* The level 1 heading will cause the following to be generated:
+
+ <?xml version="1.0" encoding="utf8" ?>
+ <!DOCTYPE chapter SYSTEM "chapter.dtd">
+ <chapter>
+ <header>
+ <copyright>
+ ...
+ </copyright>
+ <legalnotice>
+ ...
+ </legalnotice>
+
+ <title>...</title>
+ ...
+ <file>...</file>
+ </header>
+
+ ...
+
+ </chapter>
+
+ The content of copyright section and the legalnotice section will
+ contain information from a \%CopyrightBegin\%, \%CopyrightEnd\% block
+ if such exist (see below).
+
+* A level `X` heading where `1 < X <= 3` will cause the the following
+ to be generated:
+
+ <marker id="..."/>
+ <section>
+ <title>...</title>
+ ...
+ </section>
+
+ The marker id is automatically generated as a combination of all parent
+ headings up to and including level 2 separated by a `_` character. As in
+ `<marker heading 2>_<marker heading 3>_ ... _<current marker heading>`
+ where each "marker heading" is constructed as follows. All characters a-z
+ and A-Z are kept as they are, space and tab characters are replaced by
+ `-` characters, and all other characters are dropped.
+
+ This way it is relatively easy to make sure that all marker ids of a
+ document are unique, but there is of course no guarantee that they are.
+
+ The upside of these auto generated markers is that we wont have to clutter
+ the document with XML or something else while being able to refer into
+ the document. The downside is that if you change a level 2 heading you
+ change a lot of marker ids which may break links into a document from
+ other documents. That is, *be careful* when changing headings in an
+ existing document.
+
+* A level `X` heading where `3 < X` will cause the the following
+ to be generated:
+
+ <marker id="..."/>
+ <p><b>...</b></p>
+ ...
+
+ Current DTD:s used don't support deeper levels of sections, and we
+ therefore simulate a section this way. The marker id is generated as for
+ a true section (see above).
+
+* If a section enclosed by \%CopyrightBegin\% and \%CopyrightEnd\% is
+ encountered, it will be interpreted as an EPL copyright and license,
+ and will be used in the header section of the document. The
+ \%CopyrightBegin\% and \%CopyrightEnd\% "tags" will be removed from
+ the output.
+
+* All occurrences of \%OTP-REL% will be replaced by current release number
+ (e.g. R14A).
+
+* All occurrences of \%ERTS-VSN% will be replaced by current ERTS version
+ (e.g. 5.8).
+
+* Adding a `[?TOC]: true` line (optionally indented with three spaces)
+ anywhere in the document will cause a table of contents to be automatically
+ generated at the beginning of the generated document.
+
+* Unicode characters (encoded in UTF-8) are allowed and will be passed
+ through as is to the output file.
+
+Copyright and License
+---------------------
+
+%CopyrightBegin%
+
+Copyright Ericsson AB 2010. All Rights Reserved.
+
+The contents of this file are subject to the Erlang Public License,
+Version 1.1, (the "License"); you may not use this file except in
+compliance with the License. You should have received a copy of the
+Erlang Public License along with this software. If not, it can be
+retrieved online at http://www.erlang.org/.
+
+Software distributed under the License is distributed on an "AS IS"
+basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+the License for the specific language governing rights and limitations
+under the License.
+
+%CopyrightEnd%
+
+
+
+ [$ERL_TOP/INSTALL.md]: doc/installation_guide:INSTALL
+ [github]: http://github.com
+ [our github repository]: http://github.com/erlang/otp
+
+
+ [?TOC]: true
View
1  TAR.include
@@ -2,6 +2,7 @@ AUTHORS
EPLICENCE
Makefile.in
README.md
+README.md.txt
INSTALL.md
INSTALL-CROSS.md
INSTALL-WIN32.md
View
17 configure.in
@@ -182,14 +182,14 @@ AC_PROG_RANLIB
# Get erts version and otp release from erts/vsn.mk
#
AC_MSG_CHECKING([ERTS version])
-[ERTS=erts-`sed -n "s/^VSN[ ]*=[ ]*\(.*\)/\1/p" < $ERL_TOP/erts/vsn.mk`]
-AC_MSG_RESULT([$ERTS])
-AC_SUBST(ERTS)
+[ERTS_VSN=`sed -n "s/^VSN[ ]*=[ ]*\(.*\)/\1/p" < $ERL_TOP/erts/vsn.mk`]
+AC_MSG_RESULT([$ERTS_VSN])
+AC_SUBST(ERTS_VSN)
AC_MSG_CHECKING([OTP release])
-[OTP=OTP-`sed -n "s/^SYSTEM_VSN[ ]*=[ ]*\(.*\)/\1/p" < $ERL_TOP/erts/vsn.mk`]
-AC_MSG_RESULT([$OTP])
-AC_SUBST(OTP)
+[OTP_REL=`sed -n "s/^SYSTEM_VSN[ ]*=[ ]*\(.*\)/\1/p" < $ERL_TOP/erts/vsn.mk`]
+AC_MSG_RESULT([$OTP_REL])
+AC_SUBST(OTP_REL)
AC_ARG_ENABLE(threads,
[ --enable-threads enable async thread support
@@ -343,7 +343,10 @@ fi
export ERL_TOP
AC_CONFIG_SUBDIRS(lib erts)
-AC_OUTPUT(Makefile)
+AC_CONFIG_FILES([Makefile])
+AC_CONFIG_FILES([make/emd2exml], [chmod +x make/emd2exml])
+
+AC_OUTPUT
pattern="lib/*/SKIP"
files=`echo $pattern`
View
1,285 make/emd2exml.in
@@ -0,0 +1,1285 @@
+#!/usr/bin/env escript
+%% -*- erlang -*-
+%%! -smp disable
+
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%%-------------------------------------------------------------------
+%%% File : emd2exml.in
+%%% Author : Rickard Green
+%%% Description : Erlangish MarkDown To Erlangish XML
+%%%
+%%% Note that this script has *one and only one*
+%%% specific purpose. That purpose is to generate XML
+%%% that fits into the Erlang/OTP documentation, so that
+%%% the Erlang/OTP "readme" files also can be part of
+%%% the Erlang/OTP HTML and Erlang/OTP PDF
+%%% documentation. Nothing more, nothing less. It is
+%%% *not* intended as some kind of a generic Markdown to
+%%% XML tool, and never will be.
+%%%
+%%% Created : 25 Feb 2010 by Rickard Green
+%%%-------------------------------------------------------------------
+
+-define(MAX_HEADING, 3).
+
+-define(DELAYED_COPYRIGHT_IX, 0).
+-define(DELAYED_TOC_IX, 1).
+-define(DELAYED_START_IX, 2).
+
+-mode(compile).
+
+-export([main/1]).
+
+-record(state,{h = 0,
+ p = false,
+ c = no,
+ note = false,
+ warning = false,
+ emphasis = no,
+ code = false,
+ code_blank = [],
+ bq_lvl = 0,
+ mlist = [],
+ list_p = false,
+ list_type_stack = [],
+ list_p_stack = [],
+ list_lvl = 0,
+ line_no = -1,
+ line = "",
+ type = blank,
+ bq_type = 0,
+ prev_line = "",
+ prev_type = blank,
+ next_line = "",
+ next_type = blank,
+ bq_next_type = 0,
+ delayed_array,
+ delayed_array_ix = ?DELAYED_START_IX,
+ delayed_tree,
+ out = [],
+ copyright = false,
+ copyright_data = [],
+ have_h1 = false,
+ smarker_ix = false,
+ toc = [],
+ ifile,
+ ofile}).
+
+main([I, O]) ->
+ IFD = file_ropen(I),
+ S0 = get_line(get_line(#state{ifile = IFD,
+ ofile = {O, undefined},
+ delayed_array = array:new(),
+ delayed_tree = gb_trees:empty()})),
+ S1 = complete_output(parse(S0)),
+ file_close(IFD),
+ OFD = file_wopen(O),
+ write_output(OFD, S1#state.out),
+ file_close(OFD),
+ stop();
+main(_) ->
+ io:format(standard_error,
+ "Usage: emd2exml <Input Markdown File> <Output XML file>~n",[]),
+ stop(1).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%
+%% Parser
+%%
+
+%%
+%% Eof
+%%
+
+parse(#state{h = H, line = eof} = S) ->
+ sections(0, H, end_all(S));
+
+%%
+%% Note
+%%
+
+parse(#state{line = "> *NOTE*: " ++ Line,
+ note = false,
+ type = {bquote, 0, 1}} = S0) ->
+ S1 = put_line(end_all(S0#state{note = true, bq_lvl = 1}), "<note>"),
+ parse(S1#state{line = Line, type = type(Line), bq_type = 1});
+
+parse(#state{bq_lvl = 1, note = true, bq_type = 0} = S) ->
+ parse(put_line(end_all(S#state{bq_lvl = 0, note = false}), "</note>"));
+
+%%
+%% Warning
+%%
+
+parse(#state{line = "> *WARNING*: " ++ Line,
+ warning = false,
+ type = {bquote, 0, 1}} = S0) ->
+ S1 = put_line(end_all(S0#state{warning = true, bq_lvl = 1}), "<warning>"),
+ parse(S1#state{line = Line, type = type(Line), bq_type = 1});
+
+parse(#state{bq_lvl = 1, warning = true, bq_type = 0} = S) ->
+ parse(put_line(end_all(S#state{bq_lvl = 0, warning = false}), "</warning>"));
+
+%%
+%% Block quote
+%%
+
+parse(#state{note = false,
+ warning = false,
+ line = BQLine,
+ type = {bquote, TxtLvl, BQLvl}} = S0) ->
+ Line = rm_bquote(TxtLvl, BQLvl, BQLine),
+ S1 = chg_bq_lvl(BQLvl, S0),
+ parse(S1#state{line = Line, type = type(Line), bq_type = BQLvl});
+
+% This clause is also used by warning and note
+parse(#state{bq_lvl = BQLvl,
+ next_line = BQLine,
+ next_type = {bquote, TxtLvl, BQLvl}} = S) ->
+ Line = rm_bquote(TxtLvl, BQLvl, BQLine),
+ parse(S#state{next_line = Line,
+ next_type = type(Line),
+ bq_next_type = BQLvl});
+
+parse(#state{note = false,
+ warning = false,
+ bq_lvl = Lvl, bq_type = 0} = S) when Lvl /= 0->
+ parse(chg_bq_lvl(0, S));
+
+%%
+%% Multiple blank lines
+%%
+
+% Keep multiple blank lines in code otherwise get rid of them...
+parse(#state{code = false, type = blank, next_type = blank} = S) ->
+ parse(get_line(S));
+
+%%
+%% Heading
+%%
+
+parse(#state{type = {text, 0}, next_type = {marker, h1}} = S) ->
+ parse(get_line(get_line(setext_heading(1, end_all(S)))));
+parse(#state{type = {text, 0}, next_type = {marker, h2}} = S) ->
+ parse(get_line(get_line(setext_heading(2, end_all(S)))));
+parse(#state{line = "#" ++ _} = S) ->
+ parse(get_line(atx_heading(end_all(S))));
+
+%%
+%% List
+%%
+
+parse(#state{code = false,
+ list_lvl = Lvl,
+ type = blank,
+ next_type = {text, 0}} = S) when Lvl /= 0 ->
+ parse(get_line(chg_list_lvl(S, 0)));
+
+parse(#state{code = false,
+ list_lvl = Lvl,
+ type = blank,
+ next_type = {text, TxtLvl}} = S) when Lvl /= 0,
+ TxtLvl >= Lvl ->
+ parse(get_line(put_line(list_use_p(S, yes), "")));
+
+parse(#state{code = false,
+ list_lvl = Lvl,
+ type = blank,
+ next_type = {uolist, ListLvl}} = S) when Lvl /= 0,
+ ListLvl >= Lvl-1 ->
+ parse(get_line(put_line(list_use_p(S, yes), "")));
+
+parse(#state{code = false,
+ list_lvl = Lvl,
+ type = blank,
+ next_type = {olist, ListLvl}} = S) when Lvl /= 0,
+ ListLvl >= Lvl-1 ->
+ parse(get_line(put_line(list_use_p(S, yes), "")));
+
+parse(#state{code = false,
+ type = {ListType, ListLvl},
+ line = Line} = S0) when ListType == uolist; ListType == olist ->
+ S1 = list_item(end_p(S0), ListType, ListLvl),
+ S2 = list_chk_nxt_line(put_text(put_list_p(S1, start),
+ list_strip(ListType, Line))),
+ parse(get_line(S2));
+
+parse(#state{code = false,
+ list_lvl = Lvl,
+ list_p = true,
+ type = {text, _},
+ line = Line} = S0) when Lvl /= 0 ->
+ S1 = list_chk_nxt_line(put_text(S0, list_strip(Line))),
+ parse(get_line(S1));
+
+parse(#state{code = false,
+ list_lvl = Lvl,
+ list_p = false,
+ type = {text, NewLvl},
+ line = Line} = S0) when Lvl /= 0, NewLvl < Lvl ->
+ S1 = chg_list_lvl(S0, NewLvl),
+ S2 = list_chk_nxt_line(put_text(put_list_p(S1, start), list_strip(Line))),
+ parse(get_line(S2));
+
+parse(#state{code = false,
+ list_lvl = Lvl,
+ list_p = false,
+ type = {text, Lvl},
+ line = Line} = S0) when Lvl /= 0 ->
+ S1 = list_chk_nxt_line(put_text(put_list_p(S0, start), list_strip(Line))),
+ parse(get_line(S1));
+
+%%
+%% Code
+%%
+
+parse(#state{code = false,
+ list_lvl = Lvl,
+ p = false,
+ prev_type = blank,
+ type = {text, TxtLvl},
+ line = Line} = S) when TxtLvl > Lvl ->
+ Data = code(strip_lvls(Lvl+1, Line)),
+ parse(get_line(put_chars(S#state{code = true},
+ ["<code type=\"none\">", nl(), Data])));
+parse(#state{code = true, type = blank, line = CB, code_blank = CBs} = S) ->
+ parse(get_line(S#state{code_blank = [CB | CBs]}));
+parse(#state{code = true,
+ code_blank = CB,
+ list_lvl = Lvl,
+ type = {text, TxtLvl},
+ line = Line} = S) when TxtLvl > Lvl ->
+ Data = code(strip_lvls(Lvl+1, Line)),
+ parse(get_line(put_chars(S#state{code_blank = []},
+ [strip_code_blank(Lvl+1, CB), Data])));
+parse(#state{code = true,
+ prev_type = blank,
+ type = {text, 0}} = S) ->
+ parse(chg_list_lvl(end_code(S), 0));
+parse(#state{code = true} = S) ->
+ parse(end_code(S));
+
+%%
+%% Paragraph
+%%
+
+parse(#state{p = false,
+ prev_type = blank,
+ type = {text, 0},
+ next_type = blank,
+ line = Line} = S) ->
+ parse(get_line(put_line(put_text(put_line(S, "<p>"), Line), "</p>")));
+parse(#state{p = false,
+ prev_type = blank,
+ type = {text, 0},
+ line = Line} = S) ->
+ parse(get_line(put_text(put_line(S#state{p = true}, "<p>"), Line)));
+parse(#state{p = true,
+ type = {text, 0},
+ next_type = blank,
+ line = Line} = S) ->
+ parse(get_line(put_line(put_text(S#state{p = false}, Line), "</p>")));
+
+%%
+%% Resolve link
+%%
+
+parse(#state{type = resolve_link} = S) ->
+ parse(get_line(resolve_link(S)));
+
+%%
+%% Plain text
+%%
+
+parse(#state{line = Line} = S) ->
+ parse(get_line(put_text(S, Line))).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%% Auxilary functions
+%%%
+
+%%
+%% Text
+%%
+
+end_p(#state{p = false} = S) ->
+ S;
+end_p(#state{p = true} = S) ->
+ put_line(S#state{p = false}, "</p>").
+
+text(Line) ->
+ text(Line, []).
+
+text("%ERTS-VSN%" ++ Cs, Acc) ->
+ text(Cs, ["@ERTS_VSN@"|Acc]);
+text("%OTP-REL%" ++ Cs, Acc) ->
+ text(Cs, ["@OTP_REL@"|Acc]);
+
+text([$\\,C|Cs], Acc) ->
+ text(Cs, [C|Acc]);
+text([$<|Cs], Acc) ->
+ text(Cs, ["&lt;"|Acc]);
+text([$>|Cs], Acc) ->
+ text(Cs, ["&gt;"|Acc]);
+text([$&|Cs], Acc) ->
+ text(Cs, ["&amp;"|Acc]);
+text([$'|Cs], Acc) ->
+ text(Cs, ["&apos;"|Acc]);
+text([C|Cs], Acc) ->
+ text(Cs, [C|Acc]);
+text([], Acc) ->
+ lists:reverse(Acc).
+
+put_text(#state{c = CTag, emphasis = EmTag} = S, Line) ->
+ put_text(S, Line, CTag, EmTag, []).
+
+put_text(S, "%ERTS-VSN%"++Cs, CTag, EmTag, Acc) ->
+ put_text(S, Cs, CTag, EmTag, ["@ERTS_VSN@"|Acc]);
+put_text(S, "%OTP-REL%"++Cs, CTag, EmTag, Acc) ->
+ put_text(S, Cs, CTag, EmTag, ["@OTP_REL@"|Acc]);
+
+put_text(S, [$\\,C|Cs], no, EmTag, Acc) ->
+ put_text(S, Cs, no, EmTag, [C|Acc]);
+put_text(S, [C,C|Cs], no, b, Acc) when C == $*; C == $_ ->
+ put_text(S, Cs, no, no, ["</b>"|Acc]);
+put_text(S, [C,C|Cs], no, no, Acc) when C == $*; C == $_ ->
+ put_text(S, Cs, no, b, ["<b>"|Acc]);
+put_text(S, [C|Cs], no, em, Acc) when C == $*; C == $_ ->
+ put_text(S, Cs, no, no, ["</em>"|Acc]);
+put_text(S, [C|Cs], no, no, Acc) when C == $*; C == $_ ->
+ put_text(S, Cs, no, em, ["<em>"|Acc]);
+put_text(S, [$`,$`|Cs], double, EmTag, Acc) ->
+ put_text(S, Cs, no, EmTag, ["</c>"|Acc]);
+put_text(S, [$`,$`|Cs], no, EmTag, Acc) ->
+ put_text(S, Cs, double, EmTag, ["<c>"|Acc]);
+put_text(S, [$`|Cs], single, EmTag, Acc) ->
+ put_text(S, Cs, no, EmTag, ["</c>"|Acc]);
+put_text(S, [$`|Cs], no, EmTag, Acc) ->
+ put_text(S, Cs, single, EmTag, ["<c>"|Acc]);
+put_text(S, [$<|Cs], CTag, EmTag, Acc) when CTag /= no ->
+ put_text(S, Cs, CTag, EmTag, ["&lt;"|Acc]);
+put_text(S, [$>|Cs], CTag, EmTag, Acc) when CTag /= no ->
+ put_text(S, Cs, CTag, EmTag, ["&gt;"|Acc]);
+put_text(S, [$&|Cs], CTag, EmTag, Acc) when CTag /= no ->
+ put_text(S, Cs, CTag, EmTag, ["&amp;"|Acc]);
+put_text(S, [$'|Cs], CTag, EmTag, Acc)when CTag /= no ->
+ put_text(S, Cs, CTag, EmTag, ["&apos;"|Acc]);
+put_text(S, [$<|Cs], no, EmTag, Acc) ->
+ case auto_link(Cs) of
+ no -> put_text(S, Cs, no, EmTag, [$<|Acc]);
+ {URL, NewCs} -> put_text(S, NewCs, no, EmTag, [URL|Acc])
+ end;
+put_text(S0, "![" ++ Cs, no, EmTag, Acc) ->
+ put_text_link_or_image(S0, image, "![", Cs, EmTag, Acc);
+put_text(S0, [$[|Cs], no, EmTag, Acc) ->
+ put_text_link_or_image(S0, link, $[, Cs, EmTag, Acc);
+put_text(S, " \n", CTag, EmTag, Acc) ->
+ put_text(S, [], CTag, EmTag, ["<br/>\n"|Acc]);
+put_text(S, " \r", CTag, EmTag, Acc) ->
+ put_text(S, [], CTag, EmTag, ["<br/>\r"|Acc]);
+put_text(S, " \r\n", CTag, EmTag, Acc) ->
+ put_text(S, [], CTag, EmTag, ["<br/>\r\n"|Acc]);
+put_text(S, [C|Cs], CTag, EmTag, Acc) ->
+ put_text(S, Cs, CTag, EmTag, [C|Acc]);
+put_text(S0, [], CTag, EmTag, Acc) ->
+ S1 = put_chars(S0, [lists:reverse(Acc)]),
+ S1#state{c = CTag, emphasis = EmTag}.
+
+put_text_link_or_image(S0, Type, Head, Tail0, EmTag, Acc) ->
+ case link_or_image(Tail0, Type) of
+ no -> put_text(S0, Tail0, no, EmTag, [Head|Acc]);
+ {LnkOrImg, Tail1} -> put_text(S0, Tail1, no, EmTag, [LnkOrImg|Acc]);
+ {delayed, Type, Key, Text, Tail1} ->
+ chk_key(Type, Key, S0),
+ S1 = put_chars(S0, [lists:reverse(Acc)]),
+ S2 = put_delayed(S1, Key, {Type, Text, S1#state.line_no}),
+ put_text(S2, Tail1, no, EmTag, [])
+ end.
+
+%%
+%% Links
+%%
+
+chk_key(Type, [$?|_] = Key, #state{ifile = {File, _}, line_no = Line}) ->
+ error(File, Line, "~s definition name `~ts' begin with a `?' character",
+ [case Type of
+ image -> "Image";
+ _ -> "Link"
+ end,
+ Key]);
+chk_key(_, _, _) ->
+ ok.
+
+auto_link(Str) ->
+ case url(Str) of
+ no -> no;
+ Res -> Res
+ end.
+
+url(Str) ->
+ url(Str, false, []).
+
+url([$\\,C|Cs], Bool, Acc) ->
+ url(Cs, Bool, [C|Acc]);
+url([$>|_Cs], false, _Acc) ->
+ no;
+url([$>|Cs], true, Acc) ->
+ Url = text(lists:reverse(Acc)),
+ {["<url href=\"", Url, "\">", Url, "</url>"], Cs};
+url("://" ++ _Cs, true, _Acc) ->
+ no;
+url("://" ++ Cs, false, Acc) ->
+ url(Cs, true, [$/,$/,$:|Acc]);
+url([C|Cs], Bool, Acc) ->
+ url(Cs, Bool, [C|Acc]).
+
+link_or_image(Str, Type) ->
+ case link_or_image_text(Str, "") of
+ no -> no;
+ {Text, Cont1} ->
+ case link_or_image_data(Cont1, none, Type, "", "") of
+ no -> no;
+ {url, Url, _Title, Cont2} ->
+ {["<url href=\"", text(Url), "\">", text(Text), "</url>"],
+ Cont2};
+ {seealso, SeeAlso, _Title, Cont2} ->
+ {["<seealso marker=\"", text(SeeAlso), "\">",
+ text(Text), "</seealso>"],
+ Cont2};
+ {image, Image, Title, Cont2} ->
+ {["<image file=\"", text(Image), "\"><icaption>",
+ text(Title), "</icaption></image>"],
+ Cont2};
+ {delayed, text, Cont2} ->
+ {delayed, Type, Text, Text, Cont2};
+ {delayed, Key, Cont2} ->
+ {delayed, Type, Key, Text, Cont2}
+ end
+ end.
+
+link_or_image_text([$\\,C|Cs], Acc) ->
+ link_or_image_text(Cs, [C|Acc]);
+link_or_image_text([$]|_Cs], "") ->
+ no;
+link_or_image_text([$]|Cs], Acc) ->
+ {lists:reverse(Acc), Cs};
+link_or_image_text([C|Cs], Acc) ->
+ link_or_image_text(Cs, [C|Acc]);
+link_or_image_text([], _Acc) ->
+ no.
+
+link_or_image_data([C|Cs], none, link, "", "") when C == $ ; C == $\t ->
+ link_or_image_data(Cs, none, link, "", "");
+link_or_image_data([C|Cs], none, image, "", "") when C == $ ; C == $\t ->
+ link_or_image_data(Cs, none, image, "", "");
+
+link_or_image_data([$\\,C|Cs], How, Type, Eltit, Lru) when How /= none ->
+ link_or_image_data(Cs, How, Type, Eltit, [C|Lru]);
+
+link_or_image_data([$(|Cs], none, link, "", "") ->
+ link_or_image_data(Cs, {inline, read}, seealso, "", "");
+link_or_image_data([$(|Cs], none, image, "", "") ->
+ link_or_image_data(Cs, {inline, read}, image, "", "");
+link_or_image_data([$)|_Cs], {inline, _}, _Type, "", "") ->
+ no;
+link_or_image_data([$)|Cs], {inline, _}, Type, Eltit, Lru) ->
+ {Type, lists:reverse(ws_strip(Lru)), lists:reverse(ws_strip(Eltit)), Cs};
+link_or_image_data("://" ++Cs, {inline, read} = IR, seealso, Eltit, Lru) ->
+ link_or_image_data(Cs, IR, url, Eltit, [$/,$/,$:|Lru]);
+link_or_image_data([$"|Cs], {inline, read}, Type, "", Lru) ->
+ link_or_image_data(Cs, {inline, read_title}, Type, "", Lru);
+link_or_image_data([$"|Cs], {inline, read_title}, Type, Eltit, Lru) ->
+ link_or_image_data(Cs, {inline, drop}, Type, Eltit, Lru);
+link_or_image_data([C|Cs], {inline, read} = IR, Type, "", Lru) ->
+ link_or_image_data(Cs, IR, Type, "", [C|Lru]);
+link_or_image_data([C|Cs], {inline, read_title} = IRT, Type, Eltit, Lru) ->
+ link_or_image_data(Cs, IRT, Type, [C|Eltit], Lru);
+link_or_image_data([_|Cs], {inline, drop}, Type, Eltit, Lru) ->
+ link_or_image_data(Cs, {inline, drop}, Type, Eltit, Lru);
+
+link_or_image_data("[]"++Cs, none, _Type, "", "") ->
+ {delayed, text, Cs};
+link_or_image_data([$[|Cs], none, Type, "", "") ->
+ link_or_image_data(Cs, reference, Type, "", "");
+link_or_image_data(_, none, _Type, "", "") ->
+ no;
+link_or_image_data([$]|_Cs], reference, _Type, "", "") ->
+ no;
+link_or_image_data([$]|Cs], reference, _Type, "", Fer) ->
+ {delayed, lists:reverse(ws_strip(Fer)), Cs};
+link_or_image_data([C|Cs], reference, Type, "", Fer) ->
+ link_or_image_data(Cs, reference, Type, "", [C|Fer]).
+
+mk_image(Title, Url) ->
+ ["<image file=\"", text(Url), "\"><icaption>",
+ text(Title), "</icaption></image>"].
+
+mk_link(Text, Url) ->
+ case chk_proto(Url) of
+ true -> ["<url href=\"", text(Url), "\">", text(Text), "</url>"];
+ false -> ["<seealso marker=\"", text(Url), "\">", text(Text), "</seealso>"]
+ end.
+
+chk_proto("://" ++ _) ->
+ true;
+chk_proto([]) ->
+ false;
+chk_proto([_|Cs]) ->
+ chk_proto(Cs).
+
+%%
+%% Code
+%%
+
+code(Line) ->
+ code(Line, []).
+
+code("%ERTS-VSN%" ++ Cs, Acc) ->
+ code(Cs, ["@ERTS_VSN@"|Acc]);
+code("%OTP-REL%" ++ Cs, Acc) ->
+ code(Cs, ["@OTP_REL@"|Acc]);
+
+code([$<|Cs], Acc) ->
+ code(Cs, ["&lt;"|Acc]);
+code([$>|Cs], Acc) ->
+ code(Cs, ["&gt;"|Acc]);
+code([$&|Cs], Acc) ->
+ code(Cs, ["&amp;"|Acc]);
+code([$'|Cs], Acc) ->
+ code(Cs, ["&apos;"|Acc]);
+code([C|Cs], Acc) ->
+ code(Cs, [C|Acc]);
+code([], Acc) ->
+ lists:reverse(Acc).
+
+end_code(#state{code = true} = S) ->
+ put_line(S#state{code = false, code_blank = []}, "</code>");
+end_code(S) ->
+ S.
+
+strip_code_blank(_Lvls, []) ->
+ [];
+strip_code_blank(Lvls, CBs) ->
+ strip_code_blank(Lvls, CBs, []).
+
+strip_code_blank(_Lvls, [], Acc) ->
+ Acc;
+strip_code_blank(Lvls, [CB|CBs], Acc) ->
+ strip_code_blank(Lvls, CBs, [strip_lvls(Lvls, CB)|Acc]).
+
+strip_lvls(0, Str) ->
+ Str;
+strip_lvls(N, " " ++ Str) ->
+ strip_lvls(N-1, Str);
+strip_lvls(N, [$\t | Str]) ->
+ strip_lvls(N-1, Str);
+strip_lvls(_N, Str) ->
+ Str.
+
+%%
+%% Titles and sections
+%%
+
+put_title(S, 1, Title) ->
+ header(chk_h1(1, S#state{h = 1, mlist = [top]}), Title);
+put_title(#state{mlist = MList0,
+ toc = TOC,
+ smarker_ix = SMarkerIX} = S0, H, Title) ->
+ TitleStr = text(Title),
+ MList1 = [mk_lvl_marker(Title) | MList0],
+ Marker = mk_marker(MList1),
+ S1 = chk_h1(H,
+ S0#state{toc = [TOC,
+ lists:duplicate(H," "),
+ " ",
+ "<seealso marker=\"#",Marker,"\">",
+ TitleStr,"</seealso>",nl()],
+ h = H,
+ mlist = MList1,
+ smarker_ix = false}),
+ true = is_integer(SMarkerIX),
+ S2 = write_delayed(S1, SMarkerIX, ["<marker id=\"", Marker, "\"/>",nl()]),
+ {STag, ETag} = case H > ?MAX_HEADING of
+ true -> {"<p><b>", "</b></p>"};
+ false -> {"<title>", "</title>"}
+ end,
+ put_chars(S2, [STag, TitleStr, ETag, nl()]).
+
+setext_heading(H, #state{line = Line, h = OldH} = S0) ->
+ S1 = sections(H, OldH, S0),
+ put_title(S1, H, ws_strip(Line)).
+
+atx_heading(#state{line = Line, h = OldH} = S0) ->
+ {H, Title} = get_atx_title(Line),
+ S1 = sections(H, OldH, S0),
+ put_title(S1, H, ws_strip(Title)).
+
+
+get_atx_title(Line) ->
+ get_atx_title(Line, 0).
+
+get_atx_title("#" ++ Rest, H) ->
+ get_atx_title(Rest, H+1);
+get_atx_title(Rest, H) ->
+ {H, atx_strip(Rest)}.
+
+atx_strip(S) ->
+ strip(S, [$ ,$\t,$\n,$\r,$#]).
+
+chk_h1(1, #state{have_h1 = true, ifile = {File, _}, line_no = Line}) ->
+ error(File, Line, "Multiple H1 headings~n", []);
+chk_h1(1, #state{have_h1 = false} = S) ->
+ S#state{have_h1 = true};
+chk_h1(_H, S) ->
+ S.
+
+sections(0, 0, S) ->
+ S;
+sections(H, H, #state{mlist = [_|ML], toc = TOC} = S0) ->
+ S1 = S0#state{mlist = ML,
+ toc = [TOC,
+ lists:duplicate(H," "),
+ "</item><item>",nl()]},
+ S2 = end_section(H, S1),
+ begin_section(H, S2);
+sections(H, OldH, S) ->
+ sections_change(H, OldH, S).
+
+sections_change(H, H, S) ->
+ S;
+sections_change(H, OldH, #state{ifile = {File, _},
+ line_no = Line}) when H > OldH+1 ->
+ error(File, Line, "Level ~p heading without preceding level "
+ "~p heading~n", [H, H-1]);
+sections_change(H, OldH, #state{toc = TOC} = S0) when H == OldH+1 ->
+ S1 = case H > 1 of
+ false -> S0;
+ true-> S0#state{toc = [TOC, lists:duplicate(H-1," "),
+ "<list type=\"ordered\"><item>",nl()]}
+ end,
+ S2 = begin_section(H, S1),
+ sections_change(H, OldH+1, S2);
+sections_change(H, OldH, #state{mlist = [_|ML], toc = TOC} = S0) ->
+ S1 = case OldH > 1 of
+ false -> S0;
+ true-> S0#state{toc = [TOC, lists:duplicate(OldH-1," "),
+ "</item></list>",nl()]}
+ end,
+ S2 = end_section(OldH, S1),
+ sections(H, OldH-1, S2#state{mlist = ML}).
+
+begin_section(1, S) ->
+ put_line(S, "<chapter>");
+begin_section(H, #state{delayed_array_ix = IX} = S0) when H > ?MAX_HEADING ->
+ false = S0#state.smarker_ix,
+ true = is_integer(IX),
+ put_delayed(S0#state{smarker_ix = IX, delayed_array_ix = IX+1}, IX);
+begin_section(H, #state{delayed_array_ix = IX} = S0) when H > 1 ->
+ false = S0#state.smarker_ix,
+ true = is_integer(IX),
+ S1 = put_delayed(S0#state{smarker_ix = IX, delayed_array_ix = IX+1}, IX),
+ put_line(S1, "<section>");
+begin_section(_H, S) ->
+ S.
+
+end_section(1, S) ->
+ put_chars(S, ["</chapter>",nl(),nl()]);
+end_section(H, S) when H < 1; ?MAX_HEADING < H ->
+ S;
+end_section(_H, S) ->
+ put_chars(S, ["</section>",nl(),nl()]).
+
+mk_lvl_marker([C|Cs]) when $a =< C, C =< $z ->
+ [C|mk_lvl_marker(Cs)];
+mk_lvl_marker([C|Cs]) when $A =< C, C =< $Z ->
+ [C|mk_lvl_marker(Cs)];
+mk_lvl_marker([C|Cs]) when C == $ ; C == $\t ->
+ [$-|mk_lvl_marker(Cs)];
+mk_lvl_marker([_|Cs]) ->
+ mk_lvl_marker(Cs);
+mk_lvl_marker([]) ->
+ [].
+
+mk_marker([L|Ls]) ->
+ mk_marker(Ls, L).
+
+mk_marker([top], Res) ->
+ Res;
+mk_marker([L|Ls], Res) ->
+ mk_marker(Ls, [L,$_|Res]).
+
+header(#state{ofile = {File, _}} = S0, Title) ->
+ {Year, Month, Day} = erlang:date(),
+ S1 = put_line(S0, "<header>"),
+ S2 = put_delayed(S1, ?DELAYED_COPYRIGHT_IX),
+ S3 = put_chars(S2,
+ ["<title>", text(Title), "</title>", nl(),
+ "<prepared>emd2exml</prepared>", nl(),
+ "<responsible>emd2exml</responsible>", nl(),
+ "<docno>1</docno>", nl(),
+ "<approved>yes</approved>", nl(),
+ "<checked>yes</checked>", nl(),
+ "<date>",
+ integer_to_list(Year), "-",
+ integer_to_list(Month), "-",
+ integer_to_list(Day),
+ "</date>", nl(),
+ "<rev>1</rev>", nl(),
+ "<file>",File,"</file>", nl(),
+ "</header>", nl()]),
+ put_delayed(S3, ?DELAYED_TOC_IX).
+
+
+create_copyright_notice(#state{copyright_data = CRD} = S) ->
+ {From, To, Holder, Legal} = parse_crd(CRD, [], [], [], []),
+ write_delayed(S,
+ ?DELAYED_COPYRIGHT_IX,
+ ["<copyright>", nl(),
+ "<year>", From, "</year>", nl(),
+ "<year>", To, "</year>", nl(),
+ "<holder>", code(Holder),"</holder>", nl(),
+ "</copyright>", nl(),
+ "<legalnotice>", nl(),
+ code(Legal),
+ "</legalnotice>", nl(), nl()]).
+
+create_toc(#state{toc = TOC} = S) ->
+ case read_delayed(S, "?TOC") of
+ {value,{"true",[]}} ->
+ write_delayed(S,
+ ?DELAYED_TOC_IX,
+ ["<p><b>Table of Contents</b></p>", nl(), TOC]);
+ _ ->
+ write_delayed(S, ?DELAYED_TOC_IX, "")
+ end.
+
+parse_crd([], From, To, Holder, Legal) ->
+ {Year, _, _} = erlang:date(),
+ {case From of
+ [] -> integer_to_list(Year);
+ _ -> From
+ end,
+ case To of
+ [] -> integer_to_list(Year);
+ _ -> To
+ end,
+ case Holder of
+ [] -> "Ericsson AB. All Rights Reserved.";
+ _ -> Holder
+ end,
+ case Legal of
+ [] ->
+ ["The contents of this file are subject to the Erlang Public License,", nl(),
+ "Version 1.1, (the \"License\"); you may not use this file except in", nl(),
+ "compliance with the License. You should have received a copy of the", nl(),
+ "Erlang Public License along with this software. If not, it can be", nl(),
+ "retrieved online at http://www.erlang.org/.", nl(),
+ nl(),
+ "Software distributed under the License is distributed on an \"AS IS\"", nl(),
+ "basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See", nl(),
+ "the License for the specific language governing rights and limitations", nl(),
+ "under the License.", nl()];
+ _ -> Legal
+ end};
+parse_crd([Line|Lines], OldFrom, OldTo, OldHolder, Legal) ->
+ case copyright_line(Line) of
+ no -> parse_crd(Lines, OldFrom, OldTo, OldHolder, [code(Line)|Legal]);
+ {From, To, Holder} -> parse_crd(Lines, From, To, code(Holder), Legal)
+ end.
+
+copyright_line(Line) ->
+ case copyright_line(Line, start, [], []) of
+ {From, To} -> {From, To, Line};
+ _ -> no
+ end.
+
+copyright_line([], start, _, _) ->
+ no;
+copyright_line([], _, [], []) ->
+ {[], []};
+copyright_line([], _, F, []) ->
+ Year = lists:reverse(F),
+ {Year, Year};
+copyright_line("opyright "++Cs, start, [], []) ->
+ copyright_line(Cs, find_from, [], []);
+copyright_line([_|Cs], start, [], []) ->
+ copyright_line(Cs, start, [], []);
+copyright_line([C|Cs], find_from, [], []) when $0 =< C, C =< $9 ->
+ copyright_line(Cs, from, [C|[]], []);
+copyright_line([_|Cs], find_from, [], []) ->
+ copyright_line(Cs, find_from, [], []);
+copyright_line([C|Cs], from, F, []) when $0 =< C, C =< $9 ->
+ copyright_line(Cs, from, [C|F], []);
+copyright_line([_|Cs], from, F, []) ->
+ copyright_line(Cs, find_to, F, []);
+copyright_line([C|Cs], find_to, F, []) when $0 =< C, C =< $9 ->
+ copyright_line(Cs, to, F, [C|[]]);
+copyright_line([_|Cs], find_to, F, []) ->
+ copyright_line(Cs, find_to, F, []);
+copyright_line([C|Cs], to, F, T) when $0 =< C, C =< $9 ->
+ copyright_line(Cs, to, F, [C|T]);
+copyright_line(_, to, F, T) ->
+ {lists:reverse(F), lists:reverse(T)}.
+
+%%
+%% Lists
+%%
+
+put_list_p(#state{list_p_stack = [{_, IX} | _]} = S, start) ->
+ put_delayed(S#state{list_p = true}, IX);
+put_list_p(#state{list_p_stack = [{_, IX} | _]} = S, stop) ->
+ put_delayed(S#state{list_p = false}, IX+1).
+
+list_use_p(#state{list_p_stack = [{unknown, IX} | LPS]} = S0, yes) ->
+ S1 = write_delayed(S0, IX, "<p>"),
+ S2 = write_delayed(S1, IX+1, "</p>"),
+ S2#state{list_p_stack = [{yes, IX} | LPS]};
+list_use_p(#state{list_p_stack = [{unknown, IX} | LPS]} = S0, no) ->
+ S1 = write_delayed(S0, IX, ""),
+ S2 = write_delayed(S1, IX+1, ""),
+ S2#state{list_p_stack = [{no, IX} | LPS]};
+list_use_p(S, _) ->
+ S.
+
+list_chk_nxt_line(#state{list_p = false} = S) ->
+ S;
+list_chk_nxt_line(#state{next_type = {text, _}} = S) ->
+ S;
+list_chk_nxt_line(S) ->
+ put_line(put_list_p(S, stop), "").
+
+list_item(#state{list_lvl = OldLvl} = S0, ListType, ListLvl) ->
+ NewLvl = case ListLvl > OldLvl of
+ true -> OldLvl+1;
+ false -> ListLvl+1
+ end,
+ S1 = chg_list_lvl(S0, ListType, NewLvl),
+ case NewLvl =< OldLvl of
+ false ->
+ S1;
+ true ->
+ case S1#state.list_type_stack of
+ [ListType|_] ->
+ %% New item in old list
+ put_chars(S1, ["</item>", nl(), "<item>", nl()]);
+ [_|LTS] ->
+ %% New item in new list
+ [_ | LPS] = S1#state.list_p_stack,
+ IX = S1#state.delayed_array_ix,
+ S2 = list_use_p(S1, no), % Ignored if already determined
+ S3 = put_line(S2, list_end_tags()),
+ S4 = put_line(S3, list_begin_tags(ListType)),
+ S4#state{list_type_stack = [ListType|LTS],
+ list_p_stack = [{unknown, IX} | LPS],
+ delayed_array_ix = IX+2}
+ end
+ end.
+
+list_begin_tags(uolist) ->
+ "<list type=\"bulleted\"><item>";
+list_begin_tags(olist) ->
+ "<list type=\"ordered\"><item>".