diff --git a/_data/learning.yml b/_data/learning.yml
new file mode 100644
index 000000000..43c2a2f50
--- /dev/null
+++ b/_data/learning.yml
@@ -0,0 +1,102 @@
+# Categories group mini-books on the 'Learn' landing page
+#
+# 'fa-icon' refers to the font-awesome icon to display
+# next to the category on the landing page
+#
+categories:
+ - name: Getting started
+ fa-icon: fas fa-cubes
+ # - name: Advanced programming methods
+ # fa-icon: fas fa-laptop-code
+
+
+
+# Mini-books are single-page or multi-page tutorials
+#
+# 'link' refers to the 'permalink' field of the corresponding page
+#
+books:
+ - title: Quickstart Fortran Tutorial
+ description: An introduction to the Fortran syntax and its capabilities
+ category: Getting started
+ link: /learn/quickstart
+ pages:
+ - link: /learn/quickstart/hello_world
+ - link: /learn/quickstart/variables
+ - link: /learn/quickstart/arrays_strings
+ - link: /learn/quickstart/operators_control_flow
+ - link: /learn/quickstart/organising_code
+
+
+
+# Web links listed at the bottom of the 'Learn' landing page
+#
+reference-links:
+ - name: Fortran wiki
+ url: http://fortranwiki.org/
+ description: A rich collection of Fortran articles and resources in an editable wiki format
+
+ - name: "Fortran 2018 Standard Interpretation Document"
+ url: https://j3-fortran.org/doc/year/18/18-007r1.pdf
+ description: "J3/18-007r1 F2018, specification of the base Fortran 2018 language"
+
+ - name: "J3 Fortran Proposals"
+ url: https://github.com/j3-fortran/fortran_proposals
+ description: a repository for community collaboration on proposals for the Fortran Standards Committee
+
+ - name: "J3: US Fortran Standards Committee"
+ url: https://j3-fortran.org/
+ description: J3 is the US National Body for the international Fortran standards committee
+
+ - name: "WG5: International Fortran Standards Committe"
+ url: https://wg5-fortran.org/
+ description:
+
+ - name: "Scivision Fortran 2018 Examples"
+ url: https://github.com/scivision/fortran2018-examples
+ description: A github repository containing code samples for various Fortran 2018 features
+
+
+
+
+# Print books listed at the bottom of the 'Learn' landing page
+#
+reference-books:
+ - author: Metcalf, M., Reid, J. and Cohen M.
+ year: 2018
+ title: Modern Fortran Explained
+ url: https://global.oup.com/academic/product/modern-fortran-explained-9780198811893
+ edition: 5th ed
+ location: Oxford, UK
+ publisher: Oxford Universtiy Press
+
+ - author: Curcic, M.
+ year: 2020
+ title: "Modern Fortran: Building Efficient Parallel Applications"
+ url: https://www.manning.com/books/modern-fortran
+ edition: 1st ed
+ location: Shelter Island, NY
+ publisher: Manning Publications
+
+ - author: Markus, A.
+ year: 2012
+ title: "Modern Fortran in Practice"
+ url: https://www.cambridge.org/core/books/modern-fortran-in-practice/BC5BD23B2E478B4D457C5D6265BA9363
+ edition: 1st ed
+ location: Cambridge, UK
+ publisher: Cambridge University Press
+
+ - author: Chivers, I. and Sleightholme, J.
+ year: 2018
+ title: Introduction to Programming with Fortran
+ url: https://doi.org/10.1007/978-3-319-75502-1
+ edition: 4th ed
+ publisher: Springer International Publishing
+
+ - author: Chapman S. J.
+ year: 2018
+ title: Fortran for Scientists and Engineers
+ url: https://www.mheducation.com/highered/product/fortran-scientists-engineers-chapman/M9780073385891.html
+ edition: 4th ed
+ location: New York
+ publisher: McGraw-Hill Education
diff --git a/_includes/book_navbar.html b/_includes/book_navbar.html
new file mode 100644
index 000000000..186b3b3d7
--- /dev/null
+++ b/_includes/book_navbar.html
@@ -0,0 +1,90 @@
+
+
diff --git a/_layouts/book.html b/_layouts/book.html
new file mode 100644
index 000000000..f8c97456c
--- /dev/null
+++ b/_layouts/book.html
@@ -0,0 +1,56 @@
+---
+layout: default
+---
+
+{% include nav.html active="Learn" %}
+
+
+
+
+ {% include book_navbar.html %}
+
+
+
+
{{ page.title }}
+
+
+
{{ page.date | date: "%B %d, %Y" }}
+ {% if page.author != null %}
+
Authors: {{ page.author }}
+ {% endif %}
+
+
+ {{ content }}
+
+
+
+
+
+
+
diff --git a/_layouts/default.html b/_layouts/default.html
index 253ce2dd9..b8e14d909 100644
--- a/_layouts/default.html
+++ b/_layouts/default.html
@@ -29,6 +29,7 @@
{% include google_analytics.html %}
+
diff --git a/assets/css/main.css b/assets/css/main.css
index 708120a3e..5e7a317d2 100644
--- a/assets/css/main.css
+++ b/assets/css/main.css
@@ -25,6 +25,42 @@ a {
font-weight: bold;
}
+.button {
+ background-color: #734f96;
+ border: none;
+ color: white;
+ padding: 10px 32px;
+ text-align: center;
+ text-decoration: none;
+ display: inline-block;
+ font-size: 20px;
+ border-radius: 8px;
+}
+
+.button.center {
+ display: block;
+ margin: 0 auto;
+ width: fit-content;
+}
+
+.button:hover {
+ background-color: #777;
+ color: white;
+ text-decoration: none;
+}
+
+.button.blue{
+ background-color: #008CBA;
+}
+
+.button.blue:hover{
+ background-color: #777;
+}
+
+#page-nav {
+ padding-left: 20px;
+}
+
h1,
h2,
h3 {
@@ -55,11 +91,15 @@ a[target="_blank"]:after {
margin: 0 3px 0 5px;
}
-/* " except in the navbar */
+/* " except in the navbar and buttons*/
.navbar a[target="_blank"]:after {
content:'';
margin: 0px;
}
+.button[target="_blank"]:after {
+ content:'';
+ margin: 0px;
+}
/* Hide text for social navbar icons
if not on mobile device*/
@@ -106,7 +146,8 @@ pre {
}
.container-flex{
- margin: 0 15px;
+ margin: 0 auto;
+ width: 90%;
display: flex;
flex-wrap: wrap;
}
@@ -217,6 +258,35 @@ pre {
}
}
+.col-right,
+.col-fixed {
+ display: block;
+}
+
+@media (min-width: 568px) {
+ .col-right {
+ /* display: table-cell; */
+ width: 61.8%;
+ vertical-align: top;
+ margin-left: 380px;
+ min-height: 500px;
+ }
+ .col-fixed {
+ /* display: table-cell; */
+ position: fixed;
+ width: 350px;
+ height: 500px;
+ z-index: 1; /* Stay on top */
+ }
+ .col-fixed .content{
+ overflow-y: auto;
+ overflow-x: hidden;
+ height: 90%;
+ width: 100%;
+ }
+}
+
+
.front-section {
padding: 8px 0;
}
diff --git a/assets/js/page_nav.js b/assets/js/page_nav.js
new file mode 100644
index 000000000..a49b00f16
--- /dev/null
+++ b/assets/js/page_nav.js
@@ -0,0 +1,35 @@
+// If the current page contains an element with id="pagenav-sidebar"
+// then this script will populate it with elements
+// containing links to all the elements on the current page
+if (!!document.getElementById("pagenav-sidebar")){
+
+ var headings = document.querySelectorAll("h2[id]");
+
+ for (var i = 0; i < headings.length; i++) {
+ document.getElementById("page-nav").innerHTML +=
+ '
' +
+ headings[i].innerText +
+ '';
+ }
+
+ $(document).ready(function() {
+ $(window).scroll(function() {
+
+ var found = false;
+ var scrollPos = $(window).scrollTop();
+ for (var i = 0; i < headings.length; i++) {
+
+ if (scrollPos >= headings[i].offsetTop){
+ found = true;
+ $("#nav-"+headings[i].id).addClass('current');
+ } else {
+ $("#nav-"+headings[i].id).removeClass('current');
+ }
+
+ }
+
+ });
+ });
+
+}
\ No newline at end of file
diff --git a/learn/index.html b/learn/index.html
new file mode 100644
index 000000000..d0efdb61e
--- /dev/null
+++ b/learn/index.html
@@ -0,0 +1,124 @@
+---
+layout: default
+title: Learn Fortran
+description: Learning resources for beginners and experts alike
+---
+
+{% include nav.html active='Learn' %}
+
+
+
+
+
+
Getting Started
+
+
+
+ New to Fortran
+
+ Try the quickstart Fortran tutorial, to
+ get an overview of the language syntax and capabilities.
+
+
+
+ Quickstart tutorial
+
+
+
+
+
+
+ Looking for help
+
+ Ask a question in the Fortran-lang discourse - a forum
+ for friendly discussion of all things Fortran.
+
+
+
+
+ Fortran-lang Discourse
+
+
+
+
+
+
+
+
+
+
+
+
Mini-book Tutorials
+
+ {% for category in site.data.learning.categories %}
+
+
+ {% if category.fa-icon %}
+
+ {% endif %}
+ {{ category.name }}
+
+
+ {% assign catBooks = site.data.learning.books | where_exp:"book", "book.category == category.name"%}
+
+ {% for book in catBooks %}
+
+
+
{{ book.description }}
+
+ {% endfor %}
+
+
+ {% endfor %}
+
+
+
+
+
+
+
+
+
Other Resources
+
+
On the web
+
+
+ {% for refLink in site.data.learning.reference-links %}
+ -
+
+ {{ refLink.name }}
+
+ {{ refLink.description }}
+
+ {% endfor %}
+
+
+
+
In print
+
+
+ {% assign refBooks = site.data.learning.reference-books | sort: "year" | reverse %}
+ {% for refBook in refBooks %}
+ -
+ {{ refBook.author }}. {{ refBook.year }}.
+
+ {{ refBook.title }}
+ .
+ {{ refBook.edition }}.
+ {{ refBook.location }}.
+ {{ refBook.publisher }}
+
+ {% endfor %}
+
+
+
+
+
+
diff --git a/learn/index.md b/learn/index.md
deleted file mode 100644
index 4d24fc7e2..000000000
--- a/learn/index.md
+++ /dev/null
@@ -1,604 +0,0 @@
----
-layout: page
-title: Quickstart Fortran
-permalink: /learn/
-navbar: Learn
----
-
-This quickstart tutorial assumes familiarity with basic programming concepts such as types, variables, arrays, control flow and functions.
-
-
-On this page:
-
-- [Setting up a Fortran compiler](#compiler-setup)
-- [Hello world program](#hello-world)
-- [Variables, arrays & strings](#variables)
-- [Operators](#operators)
-- [Controlling program flow (if,loops)](#controlling-program-flow)
-- [Procedures (functions,subroutines)](#procedures)
-- [Modules](#modules)
-
-## Compiler setup
-
-{% include note.html content="Fortran is a compiled language which means that once written, the source code must be passed through a
-compiler to produce a machine executable that can be run." %}
-
-In this tutorial, we'll work with the free and open source
-[GNU Fortran compiler (gfortran)](https://gcc.gnu.org/fortran/),
-which is part of the
-[GNU Compiler Colection (GCC)](https://gcc.gnu.org/).
-
-To install gfortran on Linux, use your system package manager.
-Otherwise, for macOS or Windows, refer to gfortran binaries from
-[this page](https://gcc.gnu.org/install/binaries.html).
-
-To check if you have _gfortran_ setup correctly, open a terminal and run the following command :
-
-```shell
-$> gfortran --version
-```
-
-this should output something like:
-
-```
-GNU Fortran 7.5.0
-Copyright (C) 2017 Free Software Foundation, Inc.
-This is free software; see the source for copying conditions. There is NO
-warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-```
-
-## Hello world
-
-Once you have setup up your compiler, open a new file in your favourite code editor and enter the following:
-
-```fortran
-program hello
- ! This is a comment line, it is ignored by the compiler
- print *, 'Hello, World!'
-end program hello
-```
-
-Having saved your program to `hello.f90`, compile at the command line with:
-```shell
-$> gfortran hello.f90 -o hello
-```
-
-{% include note.html content=".f90 is the standard file extension for modern fortran source files.
-The 90 refers to the first modern fortran standard in 1990." %}
-
-To run your compiled program:
-```shell
-$> ./hello
-Hello, World!
-```
-
-## Variables
-
-Fortran comes with 5 built-in data types:
-
-* `integer` -- for data that represent whole numbers, positive or negative
-* `real` -- for floating-point data (not a whole number)
-* `complex` -- pair consisting of a real part and an imaginary part
-* `character` -- for text data
-* `logical` -- for data that represent boolean (true or false) values
-
-### Declaring variables
-
-{% include note.html content="Fortran is a statically typed language which means the type of each
-variable is fixed when the program is compiled - variable types cannot change while the program is running." %}
-
-__Example:__ variable declaration
-
-```fortran
-program variables
- implicit none
-
- integer :: amount
- real :: pi
- complex :: frequency
- character :: initial
- logical :: isOkay
-
-end program variables
-```
-
-{% include note.html content="Fortran code is __case-insensitive__; you don't have to worry about the
-capitalisation of your variable names but it's good practice to keep it consistent." %}
-
-Note the additional statement at the beginning of the program: `implicit none`.
-This statement tells the compiler that all variables will be explicitly declared; without
-this statement variables will be implicitly typed according to the letter they begin with.
-
-{% include important.html content="Always use the `implicit none` statement at
-the beginning of each program and procedure. Implicit typing is considered bad practice in
-modern programming since it hides information leading to more program errors." %}
-
-__Example:__ variable assignment
-
-```fortran
- amount = 10
- pi = 4.141592
- frequency = (1.0,-0.5)
- initial = 'A'
- isOkay = .false.
-```
-
-Characters are surrounded by either single (`'`) or double quotes (`"`).
-
-Logical or boolean values can be either `.true.` or `.false.`.
-
-{% include important.html title="Watch out" content="for assignment at declaration: `integer :: amount = 1`.
-__This is NOT a normal initialisation;__ it implies the `save` attribute which means that the variable retains
-its value between procedure calls. Good practice is to initialise your variables separately to their declaration." %}
-
-
-
-### Floating-point precision
-
-The desired floating-point precision can be explicitly declared using a `kind` parameter.
-The `iso_fortran_env` intrinsic module provides kind parameters for the common 32bit and 64bit floating point types.
-
-__Example:__ explicit real kind
-```fortran
-program float
- use, intrinsic :: iso_fortran_env, only: sp=>real32, dp=>real64
- implicit none
-
- real(sp) :: float32
- real(dp) :: float64
-
- float32 = 1.0_sp ! Explicit suffix for literal constants
- float64 = 1.0_dp
-
-end program float
-```
-
-{% include important.html content="Always use a `kind` suffix for floating point literal constants." %}
-
-__Example:__ c-interoperable kinds
-```fortran
-program float
- use, intrinsic :: iso_c_binding, only: sp=>c_float, dp=>c_double
- implicit none
-
- real(sp) :: float32
- real(dp) :: float64
-
-end program float
-```
-
-
-### Arrays
-
-{% include important.html content="Arrays in Fortran are __one-based__ by default; this means
-that the first element along any dimension is at index 1." %}
-
-__Example:__ static array declaration
-```fortran
-program arrays
- implicit none
-
- ! 1D integer array
- integer, dimension(10) :: array1
-
- ! An equivalent array declaration
- integer :: array2(10)
-
- ! 2D real array
- real, dimension(10,10) :: array3
-
- ! Custom lower and upper index bounds
- real :: array4(0:9)
- real :: array5(-5:5)
-
-end program arrays
-```
-
-__Example:__ array slicing
-```fortran
-program array_slice
- implicit none
-
- integer :: i
- integer :: array1(10) ! 1D integer array of 10 elements
- integer :: array2(10,10) ! 2D integer array of 100 elements
-
- array1 = [1,2,3,4,5,6,7,8,9,10] ! Array constructor
- array1 = [(i,i=1,10)] ! Implied do loop constructor
- array1(:) = 0 ! set all elements to zero
- array1(1:5) = 1 ! set first five elements to one
- array1(6:) = 1 ! set all elements after five to one
-
- print *,array1(1:10:2) ! print out elements at odd indices
- print *,array2(:,1) ! print out the first column in a 2D array
- print *,array1(10:1:-1) ! print an array in reverse
-
-end program array_slice
-```
-
-{% include note.html content="Fortran arrays are stored in __column major__ order; the first
-index varies fastest." %}
-
-__Example:__ allocatable (dynamic) arrays
-```fortran
-program allocatable
- implicit none
-
- integer, allocatable :: array1(:)
- integer, allocatable :: array2(:,:)
-
- allocate(array1(10))
- allocate(array2(10,10))
-
- ...
-
- deallocate(array1)
- deallocate(array2)
-
-end program allocatable
-```
-
-{% include note.html content="Allocatable local arrays are deallocated automatically
-when they go out of scope." %}
-
-
-### Character strings
-
-
-__Example:__ static character string
-```fortran
-program string
- implicit none
-
- character(len=4) :: first_name
- character(len=5) :: last_name
- character(10) :: full_name
-
- first_name = 'John'
- last_name = 'Smith'
-
- ! String concatenation
- full_name = first_name//' '//last_name
-
- print *, full_name
-
-end program string
-```
-
-__Example:__ allocatable character string
-```fortran
-program allocatable_string
- implicit none
-
- character(:), allocatable :: first_name
- character(:), allocatable :: last_name
-
- ! Explicit allocation statement
- allocate(character(4) :: first_name)
- first_name = 'John'
-
- ! Allocation on assignment
- last_name = 'Smith'
-
- print *, first_name//' '//last_name
-
-end program allocatable_string
-```
-
-
-## Standard input / output
-
-We can use the `print` statement introduced earlier to print variable values to `stdout`:
-
-```fortran
- print *, 'The value of amount (integer) is: ',amount
- print *, 'The value of pi (real) is: ',pi
- print *, 'The value of frequency (complex) is: ',frequency
- print *, 'The value of initial (character) is: ',initial
- print *, 'The value of isOkay (logical) is: ',isOkay
-```
-
-and the `read` statement to read values from `stdin`:
-
-```fortran
-program read_value
- implicit none
- integer :: age
-
- print *, 'Please enter your age: '
- read(*,*) age
-
- print *, 'Your age is: ',age
-
-end program read_value
-```
-
-## Operators
-
-The usual set of arithmetic operators are available, listed in order or precedence:
-
-| Operator | Description |
-|:----------------:|----------------|
-| `**` | Exponent |
-| `*` | Multiplication |
-| `/ ` | Division |
-| `+` | Addition |
-| `-` | Subtraction |
-
-
-
-{% include important.html title="Watch out" content="for accidental integer division: `1/2` is equal to `0`
-because both the numerator and denominator are integers." %}
-
-To form a logical expression the following set of relational operators are available:
-
-| Operator | Alternative | Description |
-|:----------------:|:---------------------:|-----------------------------------------------------------------|
-| `==` | `.eq.` | Tests for equality of two operands |
-| `/=` | `.ne.` | Test for inequality of two operands |
-| `> ` | `.gt.` | Tests if left operand is strictly greater than right operand |
-| `< ` | `.lt.` | Tests if left operand is strictly less than right operand |
-| `>=` | `.ge.` | Tests if left operand is greater than or equal to right operand |
-| `<=` | `.le.` | Tests if left operand is less than or equal to right operand |
-
-
-
-as well as the following logical operators:
-
-| Operator | Description |
-|:---------------------:|----------------------------------------------------------------|
-| `.and.` | TRUE if both left and right operands are TRUE |
-| `.or.` | TRUE if either left or right or both operands are TRUE |
-| `.not.` | TRUE if right operand is FALSE |
-| `.eqv.` | TRUE if left operand has same logical value as right operand |
-| `.neqv.` | TRUE if left operand has the opposite logical value as right operand |
-
-
-
-
-
-
-
-
-
-
-
-
-## Controlling program flow
-
-### Conditional construct (`if`)
-
-__Example:__ single branch `if`
-
-```fortran
- if (angle < 90.0) then
- print *, 'Angle is acute'
- end if
-```
-
-__Example:__ two-branch `if-else`
-
-```fortran
- if (angle < 90.0) then
- print *, 'Angle is acute'
- else
- print *, 'Angle is obtuse'
- end if
-```
-
-__Example:__ multi-branch `if-elseif-else`
-```fortran
- if (age < 90.0) then
- print *, 'Angle is acute'
- else if (angle < 180.0) then
- print *, 'Angle is obtuse'
- else
- print *, 'Angle is reflex'
- end if
-```
-
-
-### Loop constructs (`do`)
-
-__Example:__ `do` loop
-
-```fortran
- integer :: i
- do i=1,10
- print *, i
- end do
-```
-
-__Example:__ `do` loop with skip
-
-```fortran
- integer :: i
- do i=1,10,2
- print *, i ! Print odd numbers
- end do
-```
-
-
-__Example:__ `do while` loop
-
-```fortran
- integer :: i
- i = 1
- do while (i<11)
- print *, i
- i = i + 1
- end do
-```
-
-
-## Procedures
-
-Fortran has two forms of procedure:
-
-- __Subroutine:__ invoked by a `call` statement
-- __Function:__ invoked within an expression or assignment to which it returns a value
-
-Both subroutines and functions have access to variables in the parent scope by _argument association_;
-unless the `VALUE` attribute is specified, this is similar to call by reference.
-
-### Subroutines
-
-
-The subroutine input arguments, known as _dummy arguments_ are specified in parentheses after the subroutine name;
-the dummy argument types and attributes are declared within the body of the subroutine just like local variables.
-
-__Example:__
-
-```fortran
-! Print matrix A to screen
-subroutine print_matrix(n,m,A)
- implicit none
- integer, intent(in) :: n
- integer, intent(in) :: m
- real, intent(in) :: A(n,m)
-
- integer :: i
- do i=1,n
- print *,A(i,1:m)
- end do
-
-end subroutine print_matrix
-```
-
-
-Note the additional `intent` attribute when declaring the dummy arguments; this optional attribute signifies to the compiler whether the argument
-is 'read-only' (`intent(in)`) 'write-only' (`intent(out)`) or 'read-write' (`intent(inout)`) within the procedure.
-In this example, the subroutine does not modify its arguments, hence all arguments are `intent(in)`.
-
-{% include tip.html content="It is good practice to always specify the `intent` attribute for
-dummy arguments; this allows the compiler to check for unintentional errors and provides self-documentation." %}
-
-
-We can call this subroutine from a program using a `call` statement:
-```fortran
-program call_sub
- implicit none
-
- real :: mat(10,20)
-
- mat(:,:) = 0.0
-
- call print_matrix(10,20,mat)
-
-end program call_sub
-```
-
-{% include note.html content="This example uses a so-called _explicit-shape_ array argument since we have passed additional variables to describe
-the dimensions of the array `A`; this will not be necessary if we place our subroutine in a module as described later." %}
-
-
-### Functions
-
-```fortran
-! L2 Norm of a vector
-function vector_norm(n,vec) result(norm)
- implicit none
- integer, intent(in) :: n
- real, intent(in) :: vec(n)
- real :: norm
-
- norm = sqrt(sum(vec**2))
-
-end function vector_norm
-```
-
-To execute this function:
-
-```fortran
-program run_fcn
- implicit none
-
- real :: v(9)
- real :: vector_norm
-
- v(:) = 9
-
- print *, 'Vector norm = ',vector_norm(9,v)
-
-end program run_fcn
-```
-
-{% include tip.html content="It is good programming practice for functions not to modify their arguments - _i.e._ all function arguments should be `intent(in)` - such
-functions are known as `pure` functions. Use subroutines if your procedure needs to modify its arguments." %}
-
-
-## Modules
-
-Fortran modules contain definitions that are made accessible to programs, procedures and other modules through the `use` statement.
-They can contain data objects, type definitions, procedures and interfaces.
-
-- Modules allow controlled scoping extension whereby entity access is made explicit
-- Modules automatically generate explicit interfaces required for modern procedures
-
-{% include tip.html content="It is recommended to always place functions and subroutines
-within modules." %}
-
-__Example:__
-
-```fortran
-module my_mod
- implicit none
-
- private ! All entities are module-private by default
- public public_var, print_matrix ! Explicitly export public entities
-
- real, parameter :: public_var = 2
- integer :: private_var
-
- contains
-
- ! Print matrix A to screen
- subroutine print_matrix(A)
- real, intent(in) :: A(:,:) ! An assumed-shape dummy argument
-
- integer :: i
- do i=1,size(A,1)
- print *,A(i,:)
- end do
-
- end subroutine print_matrix
-
-end module my_mod
-```
-
-{% include note.html content="Compare this `print_matrix` subroutine with [that written outside of a module](#subroutines);
-we no longer have to explicitly pass the matrix dimensions and can instead take
-advantage of _assumed-shape_ arguments since the module will generate the required
-explicit interface for us. This results in a much simpler subroutine interface." %}
-
-To `use` the module within a program:
-```fortran
-program use_mod
- use my_mod
- implicit none
-
- real :: mat(10,10)
-
- mat(:,:) = public_var
-
- call print_matrix(mat)
-
-end program use_mod
-```
-
-__Example:__ explicit import list
-
-```fortran
- use my_mod, only: public_var
-```
-
-__Example:__ aliased import
-
-```fortran
- use my_mod, only: printMat=>print_matrix
-```
-
-{% include note.html content="Each module should be written in a separate .f90 source file. Modules need to be compiled prior to any program units that `use` them." %}
-
-
-
diff --git a/learn/quickstart/arrays_strings.md b/learn/quickstart/arrays_strings.md
new file mode 100644
index 000000000..656ac5e85
--- /dev/null
+++ b/learn/quickstart/arrays_strings.md
@@ -0,0 +1,153 @@
+---
+layout: book
+title: Arrays and strings
+permalink: /learn/quickstart/arrays_strings
+---
+
+
+
+More often than not, we need to store and operate on long lists of numbers as opposed to just the single scalar variables
+that we have been using so far; in computer programming such lists are called _arrays_.
+
+Arrays are _multidimensional_ variables which contain more than value
+where each value is accessed using one or indices.
+
+{% include important.html content="Arrays in Fortran are __one-based__ by default; this means
+that the first element along any dimension is at index 1." %}
+
+
+## Array declaration
+
+We can declare arrays of any type. There are two common notations for declaring array variables;
+using the `dimension` attribute or by appending the array dimensions in parentheses to the variable name.
+
+__Example:__ static array declaration
+```fortran
+program arrays
+ implicit none
+
+ ! 1D integer array
+ integer, dimension(10) :: array1
+
+ ! An equivalent array declaration
+ integer :: array2(10)
+
+ ! 2D real array
+ real, dimension(10,10) :: array3
+
+ ! Custom lower and upper index bounds
+ real :: array4(0:9)
+ real :: array5(-5:5)
+
+end program arrays
+```
+
+## Array slicing
+
+A powerful feature of the Fortran language is its built-in support for array operations;
+we can perform operations on all or part of an array using array _slicing_ notation:
+
+__Example:__ array slicing
+```fortran
+program array_slice
+ implicit none
+
+ integer :: i
+ integer :: array1(10) ! 1D integer array of 10 elements
+ integer :: array2(10,10) ! 2D integer array of 100 elements
+
+ array1 = [1,2,3,4,5,6,7,8,9,10] ! Array constructor
+ array1 = [(i,i=1,10)] ! Implied do loop constructor
+ array1(:) = 0 ! set all elements to zero
+ array1(1:5) = 1 ! set first five elements to one
+ array1(6:) = 1 ! set all elements after five to one
+
+ print *,array1(1:10:2) ! print out elements at odd indices
+ print *,array2(:,1) ! print out the first column in a 2D array
+ print *,array1(10:1:-1) ! print an array in reverse
+
+end program array_slice
+```
+
+{% include note.html content="Fortran arrays are stored in __column major__ order; the first
+index varies fastest." %}
+
+## Allocatable (dynamic) arrays
+
+So far we have specified the size of our array in our program code -
+this type of array is known as a _static_ array since its size is fixed when
+we compile our program.
+
+Quite often, we do not know how big our array needs to be until we run
+our program.
+For example, if we are reading data from a file of unknown size.
+
+For this problem, we need `allocatable` arrays, these are _allocated_
+while the program is runnning once we know how big the array needs to be.
+
+__Example:__ allocatable arrays
+```fortran
+program allocatable
+ implicit none
+
+ integer, allocatable :: array1(:)
+ integer, allocatable :: array2(:,:)
+
+ allocate(array1(10))
+ allocate(array2(10,10))
+
+ ...
+
+ deallocate(array1)
+ deallocate(array2)
+
+end program allocatable
+```
+
+{% include note.html content="Allocatable local arrays are deallocated automatically
+when they go out of scope." %}
+
+
+## Character strings
+
+
+__Example:__ static character string
+```fortran
+program string
+ implicit none
+
+ character(len=4) :: first_name
+ character(len=5) :: last_name
+ character(10) :: full_name
+
+ first_name = 'John'
+ last_name = 'Smith'
+
+ ! String concatenation
+ full_name = first_name//' '//last_name
+
+ print *, full_name
+
+end program string
+```
+
+__Example:__ allocatable character string
+```fortran
+program allocatable_string
+ implicit none
+
+ character(:), allocatable :: first_name
+ character(:), allocatable :: last_name
+
+ ! Explicit allocation statement
+ allocate(character(4) :: first_name)
+ first_name = 'John'
+
+ ! Allocation on assignment
+ last_name = 'Smith'
+
+ print *, first_name//' '//last_name
+
+end program allocatable_string
+```
+
diff --git a/learn/quickstart/hello_world.md b/learn/quickstart/hello_world.md
new file mode 100644
index 000000000..8ca5c98cd
--- /dev/null
+++ b/learn/quickstart/hello_world.md
@@ -0,0 +1,68 @@
+---
+layout: book
+title: Hello World
+permalink: /learn/quickstart/hello_world
+---
+
+In this part of the tutorial, we will write our first Fortran program:
+the ubiquitous _Hello World_ example.
+
+However before we can write our program, we need to ensure that we have
+a Fortran compiler set up.
+
+{% include note.html content="Fortran is a compiled language which means that once written, the source code must be passed through a
+compiler to produce a machine executable that can be run." %}
+
+## Compiler setup
+
+In this tutorial, we'll work with the free and open source
+[GNU Fortran compiler (gfortran)](https://gcc.gnu.org/fortran/),
+which is part of the
+[GNU Compiler Colection (GCC)](https://gcc.gnu.org/).
+
+To install gfortran on Linux, use your system package manager.
+Otherwise, for macOS or Windows, refer to gfortran binaries from
+[this page](https://gcc.gnu.org/install/binaries.html).
+
+To check if you have _gfortran_ setup correctly, open a terminal and run the following command :
+
+```shell
+$> gfortran --version
+```
+
+this should output something like:
+
+```
+GNU Fortran 7.5.0
+Copyright (C) 2017 Free Software Foundation, Inc.
+This is free software; see the source for copying conditions. There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+```
+
+## Hello world
+
+Once you have setup up your compiler, open a new file in your favourite code editor and enter the following:
+
+```fortran
+program hello
+ ! This is a comment line, it is ignored by the compiler
+ print *, 'Hello, World!'
+end program hello
+```
+
+Having saved your program to `hello.f90`, compile at the command line with:
+```shell
+$> gfortran hello.f90 -o hello
+```
+
+{% include note.html content=".f90 is the standard file extension for modern fortran source files.
+The 90 refers to the first modern fortran standard in 1990." %}
+
+To run your compiled program:
+```shell
+$> ./hello
+Hello, World!
+```
+
+Congratulations you've written, compiled and run your first Fortran program!
+In the next part of this tutorial we will introduce variables for storing data.
\ No newline at end of file
diff --git a/learn/quickstart/index.md b/learn/quickstart/index.md
new file mode 100644
index 000000000..44ed18143
--- /dev/null
+++ b/learn/quickstart/index.md
@@ -0,0 +1,15 @@
+---
+layout: book
+title: Quickstart tutorial
+permalink: /learn/quickstart
+---
+
+This quickstart tutorial gives an overview of the Fortran programming language
+and its syntax for common structured programming concepts including:
+types, variables, arrays, control flow and functions.
+
+The contents of this tutoral are shown in the navigation bar on the left with the current page highlighted bold.
+
+Use the _Next_ button at the bottom to start the tutorial with a _Hello World_ example.
+
+
diff --git a/learn/quickstart/operators_control_flow.md b/learn/quickstart/operators_control_flow.md
new file mode 100644
index 000000000..87a9e6ada
--- /dev/null
+++ b/learn/quickstart/operators_control_flow.md
@@ -0,0 +1,137 @@
+---
+layout: book
+title: Operators and Control Flow
+permalink: /learn/quickstart/operators_control_flow
+---
+
+One of the powerful advantages of computer algorithms, compared to simple mathematical formulae,
+comes in the form program _branching_ whereby the program can decide which instructions to
+execute next based on a logical condition.
+
+There two main forms of controlling program flow:
+
+- _Conditional_ (if): choose program path based on a boolean (true or false) value
+
+- _Loop_: repeat a portion of code multiple times
+
+
+
+## Logical operators
+Before we use a conditional branching operator, we need to be able to form
+a logical expression.
+
+To form a logical expression the following set of relational operators are available:
+
+| Operator | Alternative | Description |
+|:----------------:|:---------------------:|-----------------------------------------------------------------|
+| `==` | `.eq.` | Tests for equality of two operands |
+| `/=` | `.ne.` | Test for inequality of two operands |
+| `> ` | `.gt.` | Tests if left operand is strictly greater than right operand |
+| `< ` | `.lt.` | Tests if left operand is strictly less than right operand |
+| `>=` | `.ge.` | Tests if left operand is greater than or equal to right operand |
+| `<=` | `.le.` | Tests if left operand is less than or equal to right operand |
+
+
+
+as well as the following logical operators:
+
+| Operator | Description |
+|:---------------------:|----------------------------------------------------------------|
+| `.and.` | TRUE if both left and right operands are TRUE |
+| `.or.` | TRUE if either left or right or both operands are TRUE |
+| `.not.` | TRUE if right operand is FALSE |
+| `.eqv.` | TRUE if left operand has same logical value as right operand |
+| `.neqv.` | TRUE if left operand has the opposite logical value as right operand |
+
+
+
+
+## Conditional construct (`if`)
+
+In the following examples, a conditional `if` construct is used to print out a
+message to describe the nature of the `angle` variable:
+
+__Example:__ single branch `if`
+
+```fortran
+ if (angle < 90.0) then
+ print *, 'Angle is acute'
+ end if
+```
+
+In this first example, the code within the `if` construct is __only executed if__ the
+test expression (`angle < 90.0`) is true.
+
+{% include tip.html content="It is good practice to indent code within constructs such as `if` and `do`
+to make code more readable." %}
+
+We can add alternative branch to the construct using the `else` keyword:
+
+__Example:__ two-branch `if-else`
+
+```fortran
+ if (angle < 90.0) then
+ print *, 'Angle is acute'
+ else
+ print *, 'Angle is obtuse'
+ end if
+```
+
+Now there are two _branches_ in the `if` construct, but __only one branch is executed__ depending
+on the logical expression following the `if` keyword.
+
+We can actually add any number of branches using `else if` to specify more conditions:
+
+__Example:__ multi-branch `if-elseif-else`
+```fortran
+ if (age < 90.0) then
+ print *, 'Angle is acute'
+ else if (angle < 180.0) then
+ print *, 'Angle is obtuse'
+ else
+ print *, 'Angle is reflex'
+ end if
+```
+
+When multiple conditional expressions are used, each conditional expression is tested only if none of the previous
+expressions have evaluated to true.
+
+## Loop constructs (`do`)
+
+In the following example a `do` loop construct is used to print out the numbers in
+a sequence.
+The `do` loop has an integer _counter_ variable which is used to track which iteration of the loop
+is currently executing, in this example we use a common name for this counter variable: `i`.
+
+When we define the start of the `do` loop we use our counter variable name followed by an equals (`=`) sign
+to specify the start value and final value of our counting variable.
+
+__Example:__ `do` loop
+
+```fortran
+ integer :: i
+ do i=1,10
+ print *, i
+ end do
+```
+
+__Example:__ `do` loop with skip
+
+```fortran
+ integer :: i
+ do i=1,10,2
+ print *, i ! Print odd numbers
+ end do
+```
+
+
+__Example:__ `do while` loop
+
+```fortran
+ integer :: i
+ i = 1
+ do while (i<11)
+ print *, i
+ i = i + 1
+ end do
+```
\ No newline at end of file
diff --git a/learn/quickstart/organising_code.md b/learn/quickstart/organising_code.md
new file mode 100644
index 000000000..68998bbca
--- /dev/null
+++ b/learn/quickstart/organising_code.md
@@ -0,0 +1,177 @@
+---
+layout: book
+title: Organising code structure
+permalink: /learn/quickstart/organising_code
+---
+
+Most programming languages allow you to collect commonly-used code into
+_procedures_ that can be reused by _calling_ them from other sections of code.
+
+Fortran has two forms of procedure:
+
+- __Subroutine:__ invoked by a `call` statement
+- __Function:__ invoked within an expression or assignment to which it returns a value
+
+Both subroutines and functions have access to variables in the parent scope by _argument association_;
+unless the `VALUE` attribute is specified, this is similar to call by reference.
+
+## Subroutines
+
+The subroutine input arguments, known as _dummy arguments_ are specified in parentheses after the subroutine name;
+the dummy argument types and attributes are declared within the body of the subroutine just like local variables.
+
+__Example:__
+
+```fortran
+! Print matrix A to screen
+subroutine print_matrix(n,m,A)
+ implicit none
+ integer, intent(in) :: n
+ integer, intent(in) :: m
+ real, intent(in) :: A(n,m)
+
+ integer :: i
+ do i=1,n
+ print *,A(i,1:m)
+ end do
+
+end subroutine print_matrix
+```
+
+
+Note the additional `intent` attribute when declaring the dummy arguments; this optional attribute signifies to the compiler whether the argument
+is 'read-only' (`intent(in)`) 'write-only' (`intent(out)`) or 'read-write' (`intent(inout)`) within the procedure.
+In this example, the subroutine does not modify its arguments, hence all arguments are `intent(in)`.
+
+{% include tip.html content="It is good practice to always specify the `intent` attribute for
+dummy arguments; this allows the compiler to check for unintentional errors and provides self-documentation." %}
+
+
+We can call this subroutine from a program using a `call` statement:
+```fortran
+program call_sub
+ implicit none
+
+ real :: mat(10,20)
+
+ mat(:,:) = 0.0
+
+ call print_matrix(10,20,mat)
+
+end program call_sub
+```
+
+{% include note.html content="This example uses a so-called _explicit-shape_ array argument since we have passed additional variables to describe
+the dimensions of the array `A`; this will not be necessary if we place our subroutine in a module as described later." %}
+
+
+## Functions
+
+```fortran
+! L2 Norm of a vector
+function vector_norm(n,vec) result(norm)
+ implicit none
+ integer, intent(in) :: n
+ real, intent(in) :: vec(n)
+ real :: norm
+
+ norm = sqrt(sum(vec**2))
+
+end function vector_norm
+```
+
+To execute this function:
+
+```fortran
+program run_fcn
+ implicit none
+
+ real :: v(9)
+ real :: vector_norm
+
+ v(:) = 9
+
+ print *, 'Vector norm = ',vector_norm(9,v)
+
+end program run_fcn
+```
+
+{% include tip.html content="It is good programming practice for functions not to modify their arguments - _i.e._ all function arguments should be `intent(in)` - such
+functions are known as `pure` functions. Use subroutines if your procedure needs to modify its arguments." %}
+
+
+## Modules
+
+Fortran modules contain definitions that are made accessible to programs, procedures and other modules through the `use` statement.
+They can contain data objects, type definitions, procedures and interfaces.
+
+- Modules allow controlled scoping extension whereby entity access is made explicit
+- Modules automatically generate explicit interfaces required for modern procedures
+
+{% include tip.html content="It is recommended to always place functions and subroutines
+within modules." %}
+
+__Example:__
+
+```fortran
+module my_mod
+ implicit none
+
+ private ! All entities are module-private by default
+ public public_var, print_matrix ! Explicitly export public entities
+
+ real, parameter :: public_var = 2
+ integer :: private_var
+
+ contains
+
+ ! Print matrix A to screen
+ subroutine print_matrix(A)
+ real, intent(in) :: A(:,:) ! An assumed-shape dummy argument
+
+ integer :: i
+ do i=1,size(A,1)
+ print *,A(i,:)
+ end do
+
+ end subroutine print_matrix
+
+end module my_mod
+```
+
+{% include note.html content="Compare this `print_matrix` subroutine with [that written outside of a module](#subroutines);
+we no longer have to explicitly pass the matrix dimensions and can instead take
+advantage of _assumed-shape_ arguments since the module will generate the required
+explicit interface for us. This results in a much simpler subroutine interface." %}
+
+To `use` the module within a program:
+```fortran
+program use_mod
+ use my_mod
+ implicit none
+
+ real :: mat(10,10)
+
+ mat(:,:) = public_var
+
+ call print_matrix(mat)
+
+end program use_mod
+```
+
+__Example:__ explicit import list
+
+```fortran
+ use my_mod, only: public_var
+```
+
+__Example:__ aliased import
+
+```fortran
+ use my_mod, only: printMat=>print_matrix
+```
+
+{% include note.html content="Each module should be written in a separate .f90 source file. Modules need to be compiled prior to any program units that `use` them." %}
+
+
+
diff --git a/learn/quickstart/variables.md b/learn/quickstart/variables.md
new file mode 100644
index 000000000..fd4d35dc4
--- /dev/null
+++ b/learn/quickstart/variables.md
@@ -0,0 +1,205 @@
+---
+layout: book
+title: Variables
+permalink: /learn/quickstart/variables
+---
+
+Variables store information that can be manipulated by the program.
+Fortran is a '_strongly typed_' language, which means that each variable
+must have a type.
+
+There are 5 built-in data types in Fortran:
+
+* `integer` -- for data that represent whole numbers, positive or negative
+* `real` -- for floating-point data (not a whole number)
+* `complex` -- pair consisting of a real part and an imaginary part
+* `character` -- for text data
+* `logical` -- for data that represent boolean (true or false) values
+
+Before we can use a variable, we must _declare_ it; this tells the compiler
+the variable type and any other variable attributes.
+
+{% include note.html content="Fortran is a statically typed language which means the type of each
+variable is fixed when the program is compiled - variable types cannot change while the program is running." %}
+
+## Declaring variables
+
+The syntax for declaring variables is:
+
+```fortran
+ ::
+```
+
+where `` is one of the built-in variable types listed above and
+`` is the name that you would like to call your variable.
+
+Variable names must start with a letter and can consist of letters, numbers and underscores.
+In the following example we declare a variable for each of the built-in types.
+
+__Example:__ variable declaration
+
+```fortran
+program variables
+ implicit none
+
+ integer :: amount
+ real :: pi
+ complex :: frequency
+ character :: initial
+ logical :: isOkay
+
+end program variables
+```
+
+{% include note.html content="Fortran code is __case-insensitive__; you don't have to worry about the
+capitalisation of your variable names but it's good practice to keep it consistent." %}
+
+Note the additional statement at the beginning of the program: `implicit none`.
+This statement tells the compiler that all variables will be explicitly declared; without
+this statement variables will be implicitly typed according to the letter they begin with.
+
+{% include important.html content="Always use the `implicit none` statement at
+the beginning of each program and procedure. Implicit typing is considered bad practice in
+modern programming since it hides information leading to more program errors." %}
+
+
+Once we have declared a variable, we can assign and reassign values to it using the assignment operator `=`.
+
+__Example:__ variable assignment
+
+```fortran
+ amount = 10
+ pi = 4.141592
+ frequency = (1.0,-0.5)
+ initial = 'A'
+ isOkay = .false.
+```
+
+Characters are surrounded by either single (`'`) or double quotes (`"`).
+
+Logical or boolean values can be either `.true.` or `.false.`.
+
+{% include important.html title="Watch out" content="for assignment at declaration: `integer :: amount = 1`.
+__This is NOT a normal initialisation;__ it implies the `save` attribute which means that the variable retains
+its value between procedure calls. Good practice is to initialise your variables separately to their declaration." %}
+
+
+## Standard input / output
+
+In our _Hello World_ example, we printed text to the command window.
+This is commonly referred to as writing to `standard output` or `stdout`.
+
+We can use the `print` statement introduced earlier to print variable values to `stdout`:
+
+```fortran
+ print *, 'The value of amount (integer) is: ',amount
+ print *, 'The value of pi (real) is: ',pi
+ print *, 'The value of frequency (complex) is: ',frequency
+ print *, 'The value of initial (character) is: ',initial
+ print *, 'The value of isOkay (logical) is: ',isOkay
+```
+
+In a similar way, we can read values from the command window
+using the `read` statement:
+
+```fortran
+program read_value
+ implicit none
+ integer :: age
+
+ print *, 'Please enter your age: '
+ read(*,*) age
+
+ print *, 'Your age is: ',age
+
+end program read_value
+```
+
+This input source is commonly referred to as `standard input` or `stdin`.
+
+
+## Expressions
+The usual set of arithmetic operators are available, listed in order or precedence:
+
+| Operator | Description |
+|:----------------:|----------------|
+| `**` | Exponent |
+| `*` | Multiplication |
+| `/ ` | Division |
+| `+` | Addition |
+| `-` | Subtraction |
+
+
+
+__Example:__
+
+```fortran
+program arithmetic
+ implicit none
+
+ real :: pi
+ real :: radius
+ real :: height
+ real :: area
+ real :: volume
+
+ pi = 3.141592
+
+ print *, 'Enter cylinder base radius:'
+ read(*,*) radius
+
+ print *, 'Enter cylinder height:'
+ read(*,*) height
+
+ area = pi*radius**2.0
+ volume = area*height
+
+ print *, 'Cylinder radius is: ',radius
+ print *, 'Cylinder height is: ',height
+ print *, 'Cylinder base area is: ',area
+ print *, 'Cylinder volume is: ',volume
+
+end program arithmetic
+```
+
+
+
+
+
+
+## Floating-point precision
+
+The desired floating-point precision can be explicitly declared using a `kind` parameter.
+The `iso_fortran_env` intrinsic module provides kind parameters for the common 32bit and 64bit floating point types.
+
+__Example:__ explicit real kind
+```fortran
+program float
+ use, intrinsic :: iso_fortran_env, only: sp=>real32, dp=>real64
+ implicit none
+
+ real(sp) :: float32
+ real(dp) :: float64
+
+ float32 = 1.0_sp ! Explicit suffix for literal constants
+ float64 = 1.0_dp
+
+end program float
+```
+
+{% include important.html content="Always use a `kind` suffix for floating point literal constants." %}
+
+__Example:__ c-interoperable kinds
+```fortran
+program float
+ use, intrinsic :: iso_c_binding, only: sp=>c_float, dp=>c_double
+ implicit none
+
+ real(sp) :: float32
+ real(dp) :: float64
+
+end program float
+```
+
+In the next part we will learn how to use arrays for storing more than one
+value in a variable.
\ No newline at end of file
diff --git a/packages/index.html b/packages/index.html
index 479653759..cd4da0e3e 100644
--- a/packages/index.html
+++ b/packages/index.html
@@ -78,14 +78,14 @@
-
Featured open source projects
+
Featured open source projects
-
Browse by category
+
Browse by category
{% for sitePage in site.pages %}