grammar KeepAChangelog

rule changelog
  changelog_header unreleased_section releases_section diff_section?
end

rule changelog_header
  '# Changelog' new_line
  'All notable changes to this project will be documented in this file.' new_line
  new_line
  keep_a_changelog_format '.'? new_line
  (semver_convention new_line)?
  new_line
end

rule keep_a_changelog_format
  'The format is based on [Keep a Changelog](http' 's'? '://keepachangelog.com/en/1.0.0/)'
end

rule semver_convention
  'and this project adheres to [Semantic Versioning](http' 's'? '://semver.org/spec/v2.0.0.html).'
end

rule unreleased_section
  unreleased_header change_section? (new_line change_section)*
end

rule unreleased_header
  '## ' '['? 'Unreleased' ']'? new_line
end

rule change_section
  change_header change+
end

rule change_header
  '### ' ('Added' / 'Changed' / 'Deprecated' / 'Removed' / 'Fixed' / 'Security') new_line
end

rule change
  ('- ' / '  ') (!new_line .)+ new_line?
end

rule releases_section
  release*
end

rule release
  new_line release_header change_section? (new_line change_section)*
end

rule release_header
  '## ' '['? release_version ']'? ' - ' release_date new_line
end

rule release_version
  [0-9]+ '.' [0-9]+ '.' [0-9]+ pre_release_version metadata
end

rule pre_release_version
  ( '-' [0-9A-Za-z-]+ dot_separated_group* ) / ''
end

rule metadata
  ( '+' [0-9A-Za-z-]+ dot_separated_group*  ) / ''
end

rule dot_separated_group
  '.' [0-9A-Za-z-]+
end

rule release_date
  [0-9] [0-9] [0-9] [0-9] '-' [0-9] [0-9] '-' [0-9] [0-9]
end

rule diff_section
  new_line unreleased_diff release_diff*  initial_release?
end

rule unreleased_diff
  '[Unreleased]: ' release_url new_line
end

rule initial_release
  '[' release_version ']: ' 'https://github.com/' (!'/' .)+ '/' (!'/' .)+ '/releases/tag/v' release_version new_line
end

rule release_diff
  '[' release_version ']: ' release_url new_line
end

rule release_url
  'https://github.com/' (!'/' .)+ '/' (!'/' .)+ '/compare/' diff_version '...' diff_version
end

rule diff_version
  'HEAD' / ( 'v' release_version )
end

rule new_line
  "\n"
end

end