GithubHelp home page GithubHelp logo

alphagov / govspeak Goto Github PK

View Code? Open in Web Editor NEW
83.0 88.0 22.0 966 KB

Markdown extension library for Government editors

Home Page: http://govspeak-preview.herokuapp.com/

License: MIT License

Ruby 99.11% HTML 0.89%
govuk gem

govspeak's Introduction

Govspeak is our markdown-derived mark-up language.

Usage

Install the gem

gem install govspeak

or add it to your Gemfile

gem "govspeak"

then create a new document

require 'rubygems'
require 'govspeak'

doc = Govspeak::Document.new "^Test^"
puts doc.to_html

Changes appearing across GOV.UK

Some additional steps or considerations are needed to ensure changes to govspeak cascade across GOV.UK in a holistic way.

Once govspeak has been updated and version incremented then:

Also, consider if:

Any pages that use govspeak to generate Content will need to republished in order for the new changes to be reflected.

Extensions

In addition to the standard Markdown syntax, we have added our own extensions.

Callouts

Information callouts

^This is an information callout^

creates a callout with an info (i) icon.

<div role="note" aria-label="Information" class="application-notice info-notice">
  <p>This is an information callout</p>
</div>

Warning callouts

%This is a warning callout%

creates a callout with a warning or alert (!) icon

<div role="note" aria-label="Warning" class="application-notice help-notice">
  <p>This is a warning callout</p>
</div>

Example callout

$E
**Example**: Open the pod bay doors
$E

creates an example box

<div class="example">
  <p><strong>Example:</strong> Open the pod bay doors</p>
</div>

Highlights

Advisory (DEPRECATED: marked for removal. Use 'Information callouts' instead.)

@This is a very important message or warning@

highlights the enclosed text in yellow

<h3 role="note" aria-label="Important" class="advisory">
  <span>This is a very important message or warning</span>
</h3>

Answer (DEPRECATED: marked for removal)

{::highlight-answer}
The VAT rate is *20%*
{:/highlight-answer}

creates a large highlight box with optional preamble text and giant text denoted with **

<div class="highlight-answer">
  <p>The VAT rate is <em>20%</em></p>
</div>

Statistic headline

Used in HTML publications.

Statistic headlines highlight important numbers in content. Displays a statistic as a large number with a description. The statistic and description must make sense when read aloud. The important number must be wrapped in **.

{stat-headline}
*13.8bn* years since the big bang
{/stat-headline}

Creates the following:

<div class="stat-headline">
  <p><em>13.8bn</em> years since the big bang</p>
</div>

Points of Contact

Contact

$C
**Student Finance England**
**Telephone:** 0845 300 50 90
**Minicom:** 0845 604 44 34
$C

creates a contact box

<div class="contact">
  <p>
    <strong>Student Finance England</strong><br>
    <strong>Telephone:</strong> 0845 300 50 90<br>
    <strong>Minicom:</strong> 0845 604 44 34
  </p>
</div>

Address

$A
Hercules House
Hercules Road
London SE1 7DU
$A

creates an address box

<div class="address">
  <div class="adr org fn">
    <p>
      Hercules House<br>
      Hercules Road<br>
      London SE1 7DU<br>
    </p>
  </div>
</div>

Downloads

$D
[An example form download link](http://example.com/ "Example form")

Something about this form download
$D

creates a file download box

<div class="form-download">
  <p><a href="http://example.com/" title="Example form" rel="external">An example form download link.</a></p>
</div>

Place

$P
This is a place
$P

creates a place box

<div class="place">
  <p>This is a place</p>
</div>

Information

$I
This is information
$I

creates an information box

<div class="information">
  <p>This is information</p>
</div>

Additional Information

$AI
This is additional information
$AI

creates an additional information box

<div class="additional-information">
  <p>This is additional information</p>
</div>

Call to Action

$CTA
This is a call to action
$CTA

creates an additional information box

<div class="call-to-action">
  <p>This is a call to action</p>
</div>

Summary

$!
This is a summary
$!

creates a summary box

<div class="summary">
  <p>This is a summary</p>
</div>

External Link

x[External Report](https://example.com/report)x

creates a link specified as external

<a href="https://example.com/report" rel="external">External Report</a>

Steps

Steps can be created similar to an ordered list:

s1. numbers
s2. to the start
s3. of your list

Note that steps need an extra line break after the final step (ie. two full blank lines) or other markdown directly afterwards won't work. If you have a subhead after - add a line break after this.

Legislative Lists

For lists where you want to specify the numbering and have multiple indent levels.

$LegislativeList
* 1. Item 1
* 2. Item 2
  * a) Item 2a
  * b) Item 2b
    * i. Item 2 b i
    * ii. Item 2 b ii
* 3. Item 3
$EndLegislativeList
(to indent, add 2 spaces)

Devolved content

:england:content goes here:england:
:scotland:content goes here:scotland:
:london:content goes here:london:
:wales:content goes here:wales:
:northern-ireland:content goes here:northern-ireland:
:england-wales:content goes here:england-wales:

will create a box for the specified locality

<div class="devolved-content england">
  <p class="devolved-header">This section applies to England</p>
  <div class="devolved-body">
    <p>content goes here</p>
  </div>
</div>

Tables

Tables follow the Kramdown syntax for tables with one addition - table headers can be specified by adding a # at the start of the cell. A table header inside the table head will be given a scope of col; a table header outside will be given a scope of row.

|               |# Column header one |# Column header two |
|---------------|--------------------|--------------------|
|# Row header 1 | Content #1         | Content #2         |
|# Row header 1 | Content #3         | Content #4         |
<table>
  <thead>
    <tr>
      <td></td>
      <th scope="col">Column header one</th>
      <th scope="col">Column header two</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th scope="row">Row header 1</th>
      <td>Content #1</td>
      <td>Content #2</td>
    </tr>
    <tr>
      <th scope="row">Row header 2</th>
      <td>Content #3</td>
      <td>Content #4</td>
    </tr>
  </tbody>
</table>

Barcharts

For when you want a table to be progressively enhanced by Javascript to be rendered as a bar chart.

|col|
|---|
|val|
{barchart}

will be rendered as

<table class="js-barchart-table mc-auto-outdent">
  <thead>
    <tr>
      <th>col</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>val</td>
    </tr>
  </tbody>
</table>

Embedded Content

Embedded content allows authors to reference a supporting item of a document by referencing an id. The details of this content is passed to the publishing application to govspeak at the time of rendering.

Attachments

Attachments can be be rendered as blocks

[Attachment:file.txt]

with options provided

{
  attachments: [
    {
      id: "file.txt",
      title: "My attached file",
      url: "http://example.com/file.txt",
      filename: "file.txt",
      content_type: "text/plain",
      file_size: 1024,
    }
  ]
}

will output an attachment block

<section class="gem-c-attachment">
  <div class="gem-c-attachment__thumbnail">
    <a class="govuk-link" target="_self" tabindex="-1" aria-hidden="true" href="http://example.com/file.txt">
        <svg class="gem-c-attachment__thumbnail-image" version="1.1" viewbox="0 0 84 120" width="84" height="120" aria-hidden="true">
  <path d="M74.85 5v106H5" fill="none" stroke-miterlimit="10" stroke-width="2"></path>
  <path d="M79.85 10v106H10" fill="none" stroke-miterlimit="10" stroke-width="2"></path>
</svg>

</a>
</div>
  <div class="gem-c-attachment__details">
    <h2 class="gem-c-attachment__title">
      <a class="govuk-link" target="_self" href="http://example.com/file.txt">My attached file</a>
</h2>
      <p class="gem-c-attachment__metadata"><span class="gem-c-attachment__attribute">Plain Text</span>, <span class="gem-c-attachment__attribute">1 KB</span></p>


</div></section>

Attachment Links

Attachments can be be rendered inline as links

Some information about [AttachmentLink:file.pdf]

with options provided

{
  attachments: [
    {
      id: "file.pdf",
      title: "My PDF",
      url: "http://example.com/file.pdf",
      filename: "file.pdf",
      content_type: "application/pdf",
      file_size: 32768,
      number_of_pages: 2,
    }
  ]
}

will output an attachment link within a paragraph of text

<p>Some information about <span class="gem-c-attachment-link">
  <a class="govuk-link" href="http://example.com/file.pdf">My PDF</a>

  (<span class="gem-c-attachment-link__attribute"><abbr title="Portable Document Format" class="gem-c-attachment-link__abbr">PDF</abbr></span>, <span class="gem-c-attachment-link__attribute">32 KB</span>, <span class="gem-c-attachment-link__attribute">2 pages</span>)
</span></p>

Inline Attachments (DEPRECATED: use AttachmentLink:attachment-id instead)

Attachments can be linked to inline

Details referenced in [embed:attachments:inline:34f6dda0-21b1-4e78-8120-3ff4dcea522d]

with options provided

{
  attachments: [
    {
      content_id: "34f6dda0-21b1-4e78-8120-3ff4dcea522d",
      title: "My Thorough Study",
      url: "http://example.com/my-thorough-study.pdf",
    }
  ]
}

will output an attachment within a block of text

<p>Details referenced in <span class="attachment-inline"><a href="http://example.com/my-thorough-study.pdf">My Thorough Study</a></span></p>

Image Attachments (DEPRECATED: use Image:image-id instead)

Attachments can be used to embed an image within the document

[embed:attachments:image:45ee0eea-bc53-4f14-81eb-9e75d33c4d5e]

with options provided

{
  attachments: [
    {
      content_id: "45ee0eea-bc53-4f14-81eb-9e75d33c4d5e",
      title: "A lovely landscape",
      url: "http://example.com/lovely-landscape.jpg",
    }
  ]
}

will output a image section

<figure class="image embedded">
  <div class="img">
    <img src="http://example.com/lovely-landscape.jpg" alt="A Lovely Landscape">
  </div>
</figure>

Images

Images can be embedded as a figure with optional caption.

[Image:filename.png]

with options provided

{
  images: [
    {
      alt_text: "Some alt text",
      caption: "An optional caption",
      credit: "An optional credit",
      url: "http://example.com/lovely-landscape.jpg",
      id: "filename.png",
    }
  ]
}

will output a image section

<figure class="image embedded">
  <div class="img">
    <img src="http://example.com/lovely-landscape.jpg" alt="Some alt text">
    <figcaption>
      <p>An optional caption</p>
      <p>Image credit: An optional credit</p>
    </figcaption>
  </div>
</figure>

Link

Links to different documents can be embedded so they change when the documents they reference change.

A link to [embed:link:c636b433-1e5c-46d4-96b0-b5a168fac26c]

with options provided

{
  links: [
    {
      url: "http://example.com",
      title: "An excellent website",
    }
  ]
}

will output

<p>A link to <a href="http://example.com">An excellent website</a></p>

Contact

[Contact:df62690f-34a0-4840-a7fa-4ef5acc18666]

with options provided

{
  contacts: [
    {
      id: 123,
      content_id: "df62690f-34a0-4840-a7fa-4ef5acc18666",
      title: "Government Digital Service",
      email: "[email protected]",
      contact_numbers: [
        { label: "helpdesk", number: "+4412345 67890"}
      ]
    }
  ]
}

will output

<div id="contact_123" class="contact">
  <div class="content">
    <div class="vcard contact-inner">
      <p>Government Digital Service</p>
      <div class="email-url-number">
        <p class="email">
          <span class="type">Email</span>
          <a href="mailto:[email protected]" class="email">[email protected]</a>
        </p>
        <p class="tel">
          <span class="type">helpdesk</span>
          +4412345 67890
        </p>
      </div>
    </div>
  </div>
</div>

Button

An accessible way to add button links into content, that can also allow cross domain tracking with Google Analytics

This button component uses the component from the components gem for use in govspeak.

You must use the link syntax within the button tags.

Examples

To get the most basic button.

{button}[Continue](https://gov.uk/random){/button}

which outputs

<a role="button" class="gem-c-button govuk-button" href="https://gov.uk/random">
  Continue
</a>

To turn a button into a 'Start now' button, you can pass start to the button tag.

{button start}[Start Now](https://gov.uk/random){/button}

which outputs

<a role="button" class="gem-c-button govuk-button govuk-button--start" href="https://gov.uk/random">
  Start Now
  <svg class="govuk-button__start-icon" xmlns="http://www.w3.org/2000/svg" width="17.5" height="19" viewBox="0 0 33 40" role="presentation" focusable="false"><path fill="currentColor" d="M0 0h13l20 20-20 20H0l20-20z"></path></svg>
</a>

You can pass a Google Analytics tracking id which will send page views to another domain, this is used to help services understand the start of their users journeys.

{button start cross-domain-tracking:UA-XXXXXX-Y}
  [Start Now](https://example.com/external-service/start-now)
{/button}

which outputs

<a
  role="button"
  class="gem-c-button govuk-button govuk-button--start"
  href="https://example.com/external-service/start-now"
  data-module="cross-domain-tracking"
  data-tracking-code="UA-XXXXXX-Y"
  data-tracking-name="govspeakButtonTracker"
>
  Start Now
  <svg class="govuk-button__start-icon" xmlns="http://www.w3.org/2000/svg" width="17.5" height="19" viewBox="0 0 33 40" role="presentation" focusable="false"><path fill="currentColor" d="M0 0h13l20 20-20 20H0l20-20z"></path></svg>
</a>

Licence

MIT License

govspeak's People

Contributors

alext avatar baisa avatar boffbowsh avatar bradwright avatar brucebolt avatar danacotoran avatar deborahchua avatar dependabot[bot] avatar dougdroper avatar elliotcm avatar evilstreak avatar floehopper avatar fofr avatar heathd avatar injms avatar jamiecobbett avatar jkempster34 avatar jonathanhallam avatar jordanhatch avatar jystewart avatar kalleth avatar kevindew avatar lazyatom avatar leenagupte avatar maxgds avatar murilodalri avatar nickcolley avatar ollietreend avatar techbelly avatar theseanything avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

govspeak's Issues

to_html should be safe by default

Instead of to_html returning unsanitised, exploitable HTML, it would be a safer default if to_html were an alias for to_sanitized_html, with something like to_unsanitized_html to permit unsafe use if needed.

I'd be happy to prepare a pull request if this is likely to be accepted – the change is small but there's a bit of hassle involved because the tests of generated HTML are currently very brittle.

Upgrade sanitize gem

Hello,

I'm trying to upgrade sanitize gem on govspeak to version 3.0.0, this is to bump nokogiri to 1.7.1 to prevent CVE-2016-4658 (sparklemotion/nokogiri#1615) - doing so would probably unblock me to bump nokogiri on policy-publisher, but I'm not very familiar with neither govspeak or sanitize, and I got two tests failing because the html/style seems to no longer be the output.

Do you happen to know how I could fix it? I've created a commit with the example in the message here: 3fd603e

Thanks

Add tags for displaying document amendments

We've come across a user need to display, on GOV.UK guidance pages, additions and deletions in HTML versions of legal documents. We've not been able to find a way to do this. We can in PDFs though. For example, the Digital Marketplace has published this 'contract variation':

https://www.gov.uk/government/uploads/system/uploads/attachment_data/file/558098/g-cloud-8-contract-variation-05-10-2016.pdf

In this PDF, it's obvious to sighted users what's changed (the green/red+strikeout coding is clear). The doc is probably accessible too as we believe the amendments are distinguished by screen-readers.

However, govspeak currently doesn't let us use colour in the same way for HTML. It does allow us to use the del and u tags but they're not as clear. Can we add govspeak support for these specific uses of color? Are there any other markup-related recommendations to meet these user needs?

Thanks!

Andy McAleer, content designer in GDS

Should `{::reverse}{:/reverse}` be removed?

We currently allow content editors to reverse their text using:
{::reverse}This text will be reversed{:/reverse}

It looks like this was the first extension to be added, but the commit doesn't give context for its use: 4117770

My guess would be that this is a hangover from some early govspeak tests. Unless anyone can provide some light on it?

Has it been used anywhere?

Should rexml be added as a dependancy

I've just added the govspeak gem to a Rails 7.0.2.3 app in a Ruby 3.1.0 environment. On starting the app (via rails s) I got the error cannot load such file -- rexml/parsers/baseparser (LoadError) (backtrace below).

I was able to fix the problem by adding gem "rexml" to my Gemfile.

As it appears that rexml is a requirement for govspeak, should it be added to the gemspec dependencies?

/home/rob/.rvm/gems/ruby-3.1.0/gems/bootsnap-1.11.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:15:in `require': cannot load such file -- rexml/parsers/baseparser (LoadError)
	from /home/rob/.rvm/gems/ruby-3.1.0/gems/bootsnap-1.11.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:15:in `require'
	from /home/rob/.rvm/gems/ruby-3.1.0/gems/kramdown-1.10.0/lib/kramdown/parser/html.rb:10:in `<main>'
	from /home/rob/.rvm/gems/ruby-3.1.0/gems/bootsnap-1.11.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require'
	from /home/rob/.rvm/gems/ruby-3.1.0/gems/bootsnap-1.11.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require'
	from /home/rob/.rvm/gems/ruby-3.1.0/gems/kramdown-1.10.0/lib/kramdown/parser/kramdown/html.rb:10:in `<main>'
	from /home/rob/.rvm/gems/ruby-3.1.0/gems/bootsnap-1.11.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require'
	from /home/rob/.rvm/gems/ruby-3.1.0/gems/bootsnap-1.11.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require'
	from /home/rob/.rvm/gems/ruby-3.1.0/gems/kramdown-1.10.0/lib/kramdown/parser/kramdown/paragraph.rb:14:in `<main>'
	from /home/rob/.rvm/gems/ruby-3.1.0/gems/bootsnap-1.11.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require'
	from /home/rob/.rvm/gems/ruby-3.1.0/gems/bootsnap-1.11.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require'
	from /home/rob/.rvm/gems/ruby-3.1.0/gems/kramdown-1.10.0/lib/kramdown/parser/kramdown.rb:336:in `<class:Kramdown>'
	from /home/rob/.rvm/gems/ruby-3.1.0/gems/kramdown-1.10.0/lib/kramdown/parser/kramdown.rb:60:in `<module:Parser>'
	from /home/rob/.rvm/gems/ruby-3.1.0/gems/kramdown-1.10.0/lib/kramdown/parser/kramdown.rb:19:in `<module:Kramdown>'
	from /home/rob/.rvm/gems/ruby-3.1.0/gems/kramdown-1.10.0/lib/kramdown/parser/kramdown.rb:17:in `<main>'
	from /home/rob/.rvm/gems/ruby-3.1.0/gems/bootsnap-1.11.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require'
	from /home/rob/.rvm/gems/ruby-3.1.0/gems/bootsnap-1.11.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require'
	from /home/rob/.rvm/gems/ruby-3.1.0/gems/govspeak-3.6.2/lib/kramdown/parser/kramdown_with_automatic_external_links.rb:23:in `<module:Parser>'
	from /home/rob/.rvm/gems/ruby-3.1.0/gems/govspeak-3.6.2/lib/kramdown/parser/kramdown_with_automatic_external_links.rb:22:in `<module:Kramdown>'
	from /home/rob/.rvm/gems/ruby-3.1.0/gems/govspeak-3.6.2/lib/kramdown/parser/kramdown_with_automatic_external_links.rb:4:in `<main>'
	from /home/rob/.rvm/gems/ruby-3.1.0/gems/bootsnap-1.11.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require'
	from /home/rob/.rvm/gems/ruby-3.1.0/gems/bootsnap-1.11.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require'
	from /home/rob/.rvm/gems/ruby-3.1.0/gems/govspeak-3.6.2/lib/govspeak.rb:7:in `<main>'
	from /home/rob/.rvm/gems/ruby-3.1.0/gems/bootsnap-1.11.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require'
	from /home/rob/.rvm/gems/ruby-3.1.0/gems/bootsnap-1.11.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require'
	from /home/rob/.rvm/rubies/ruby-3.1.0/lib/ruby/3.1.0/bundler/runtime.rb:60:in `block (2 levels) in require'
	from /home/rob/.rvm/rubies/ruby-3.1.0/lib/ruby/3.1.0/bundler/runtime.rb:55:in `each'
	from /home/rob/.rvm/rubies/ruby-3.1.0/lib/ruby/3.1.0/bundler/runtime.rb:55:in `block in require'
	from /home/rob/.rvm/rubies/ruby-3.1.0/lib/ruby/3.1.0/bundler/runtime.rb:44:in `each'
	from /home/rob/.rvm/rubies/ruby-3.1.0/lib/ruby/3.1.0/bundler/runtime.rb:44:in `require'
	from /home/rob/.rvm/rubies/ruby-3.1.0/lib/ruby/3.1.0/bundler.rb:176:in `require'
	from /home/rob/web/dfe/early-years-foundation-recovery/config/application.rb:19:in `<main>'
	from /home/rob/.rvm/gems/ruby-3.1.0/gems/bootsnap-1.11.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require'
	from /home/rob/.rvm/gems/ruby-3.1.0/gems/bootsnap-1.11.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require'
	from /home/rob/.rvm/gems/ruby-3.1.0/gems/railties-7.0.2.3/lib/rails/commands/server/server_command.rb:137:in `block in perform'
	from <internal:kernel>:90:in `tap'
	from /home/rob/.rvm/gems/ruby-3.1.0/gems/railties-7.0.2.3/lib/rails/commands/server/server_command.rb:134:in `perform'
	from /home/rob/.rvm/gems/ruby-3.1.0/gems/thor-1.2.1/lib/thor/command.rb:27:in `run'
	from /home/rob/.rvm/gems/ruby-3.1.0/gems/thor-1.2.1/lib/thor/invocation.rb:127:in `invoke_command'
	from /home/rob/.rvm/gems/ruby-3.1.0/gems/thor-1.2.1/lib/thor.rb:392:in `dispatch'
	from /home/rob/.rvm/gems/ruby-3.1.0/gems/railties-7.0.2.3/lib/rails/command/base.rb:87:in `perform'
	from /home/rob/.rvm/gems/ruby-3.1.0/gems/railties-7.0.2.3/lib/rails/command.rb:48:in `invoke'
	from /home/rob/.rvm/gems/ruby-3.1.0/gems/railties-7.0.2.3/lib/rails/commands.rb:18:in `<main>'
	from /home/rob/.rvm/gems/ruby-3.1.0/gems/bootsnap-1.11.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require'
	from /home/rob/.rvm/gems/ruby-3.1.0/gems/bootsnap-1.11.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require'
	from bin/rails:4:in `<main>'

HTML line-break elements not appearing in "contact" containers

According to the relevant section of the README, lines demarcated with $C are supposed to be wrapped in a div with class contact and each line is supposed to be separated by a line-break elements <br />. The wrapping is working as described, but it appears that no line-break elements are being added.

I think this is why the formatting of the Tax Credit Helpline contact details on pages like this one are not formatted as I would expect based on the source govspeak markup

Does anyone know whether this govspeak behaviour is intentional (and the docs are out-of-date) or is the behaviour incorrect?

Note that there looks as if there's specific code in place to add line-breaks for address containers (demarcated by $A).

Table headers don't support subscript or superscript

As a content publisher publishing tables of mathematical or scientific data, I need to be able to format characters as superscript and subscript in table headers so that I can express chemical and mathematical symbols.

Quite a specific use case but for things like mg/m3 or SO2, govspeak doesn't seem to allow this in headers.

Example:

| Fuel sulfur % by mass | ELV SO2 (mg/m<sup>3</sup>) at 3% O<sub>2</sub> | ELV SO<sub>2</sub> (mg/m<sup>3</sup>) at 15% O<sub>2</sub> | | --- | --- | | 0.2% | 350 | 120 | | 0.5% | 850 | 290 | | 1.0% | 1700 | 570 |

The desired output is something like the below:

Fuel sulfur % by mass ELV SO2 (mg/m3) at 3% O2 ELV SO2 (mg/m3) at 15% O2
0.2% 350 120
0.5% 850 290
1.0% 1700 570

Raised on behalf of Esther Woods (Content Designer): https://gds.slack.com/archives/CAB4PSQKW/p1612529109158600

[unofficial RFC] CSS is missing, opinions on moving govspeak CSS into govspeak.

as a user of the govspeak gem, i wish all documentation in one place, and a living style guide embedded in the gem.

This will make it easier to display changes, keep documentation up to date, and keep things consistent, it also makes it easier than trying to switch between static and govspeak.to develop. a lot of the code is a divergent, and it would be good to sort it. Currently there is three places the CSS lives.

The CSS is in the these.places currently
government frontend
the mainstream publisher
frontend.

Phone number links in contacts / text?

Use Case

As a user, I want to be able to click on a phone number from my mobile browser and have my phone call the number.

At the moment, phone numbers are rendered in plain text. Depending on the browser, they may be clickable.

Additionally, the user may not know that they need to add an international dialling code (+44 for UK numbers).

Suggestions

  • Repurpose the email syntax, so <020 7946 0123> is automatically converted to <a href="tel:+442079460123>020 7946 0123</a>
  • Validate the regular Markdown of [020 7946 0123](tel:+442079460123)
  • Use a magic token like $P to indicate a Phone Number.

Additional

Perhaps add some metadata / microformat to help with indexing / search?

References

Preventing accessibility issues before publishing

There are a number of common accessibility issues which are frequently included in our documents.
They are currently being published without any automatic detection, and publishers are unaware that they are inadvertently publishing inaccessible documents.

We are hoping to add some new functionality to Govspeak to allow certain accessibility issues to be detected and the user alerted at the earliest possible opportunity.

How

Our proposed approach is to add an AccessibilityValidator class similar to the existing HtmlValidator. The AccessibilityValidator will have access to a range of additional methods to parse submitted GovSpeak and detect accessibility issues.

The AccessibilityValidator will be able to accept arguments to allow certain rules to be enabled or disabled.

Consuming applications that wish to use the AccessibilityValidator will create their own interface similar to Whitehall's SafeHtmlValidator, and any models can then set their required accessibility rules to validate against.

validates_with AccessibilityValidator, attribute: :body, accessibility_rules: [:foo, :bar]

Should an attribute fail any of the rules, a standard Rails validation error will then be displayed upon attempting to save, allowing the user to correct the issue and prevent any further accessibility issues being published.

Request

Please ask any questions or point out any concerns or issues about this approach.

Escaped HTML generated when "important" extension is used within a paragraph

We're seeing what appears to be a bug in govspeak. Has anyone come across a problem like the following?

The following works fine :-

> puts Govspeak::Document.new(%{@ something important @}).to_html
<h3 class="advisory"><span>something important</span></h3>

But the following incorrectly escapes the HTML :-

> puts Govspeak::Document.new(%{another line\n@ something important @}).to_html
<p>another line&lt;h3 class="advisory"&gt;<span>something important</span>&lt;/h3&gt;</p>

The govspeak extensions appear to pre-process the document using regexes before handing it off to Kramdown which does the markdown conversion. In the problem case, the HTML generated by the extension is escaped my Kramdown, presumably because it sees it as part of the paragraph starting with "another line".

I can fix the problem I'm seeing by having the govspeak "important" extension insert two newlines at the beginning of the HTML it inserts, which gives the following results :-

> puts Govspeak::Document.new(%{@ something important @}).to_html

<h3 class="advisory"><span>something important</span></h3>

> puts Govspeak::Document.new(%{another line\n@ something important @}).to_html
<p>another line</p>

<h3 class="advisory"><span>something important</span></h3>

Does this seem like a reasonable solution? I believe it is a problem for at least some (if not all) of the other govspeak extensions.

Tables lacking row headers make them less accessible

Lots of tables on gov.uk are less accessible because they don't have row headers (i.e. a th as the first cell(s) in a row). If a cell cannot be understood without the context of the column header and/or row header, it is a barrier for screen reader users. Some tables need column headers, some need row headers and some need both, depending on context.

The main reason for missing row headers is that govspeak (or markdown/kramdown) doesn't support it.
(Whenever any Markdown flavour is asked to implement it, their usual response is "Use HTML!" even though an additional th syntax wouldn't make things much more complex and the majority of other plain text markup languages have a specific syntax for ths.)

A good syntax for a new implementation (either via a kramdown extension or a govspeak hack) I would like to propose is to add a # after the pipe. Using a # would be intuitive as it's already used for headings. For example:

|                 |# Second Column  |# Third Column          |
| :-------------- | :-------------: | ---------------------: |
|# First row      | Cell            | Very long data entry   |
|# Second row     | Cell            | Cell                   |
|# Third row      | Cell that spans across two columns      ||

(This example also includes a proposed syntax for merging cells, the second most needed feature to make govspeak tables more accessible.)

Extensions don't require closing tags

Hi

none of the govspeak extensions require closing tags.

I've fixed one reported issue with the 'external link' extension. The report was:

Steps to reproduce :-

  1. Create a new document (I've only tried with policy, but suspect it works with any type)
  2. Enter a body of just "xyz"
  3. Save
  4. See the body rendered as "yz{:rel=’external’}" in the admin preview.

I fixed this by requiring an opening of x[ . However it would be better if we could require a matching close tag for many of the extensions. We probably need to review our content before making such a change.

David

Is this gem intended to be used standalone?

Some time ago I created a small Govspeak prototype kit which was heavily used by the DfE as part of the early COVID-19 response - its purpose was to allow content to be researched with users prior to publishing.

That application is a static site generator and should have minimal dependencies. Unfortunately, requiring in govspeak pulls in GOV.UK Publishing Components which pulls in Rails; it's all a bit unwieldy.

As far as I can see there's only a minimal need for the publishing components by this gem, is it necessary to make it a concrete requirement? It's fine if the answer is 'yes', it might be easier for us to just support plain Markdown and apply our own extensions if and when we need them.

Possible issue with link generation

Hi,

On this page: https://www.gov.uk/smoking-at-work-the-law

The link to the bilingual signs is being generated incorrectly, with the title becoming part of the link.

The original source from the api (https://www.gov.uk/smoking-at-work-the-law.json) is:

 [bilingual signs](http://new.wales.gov.uk/smokingbanwalessub/home/guidance/signage/signage/?lang=en “Bilingual No Smoking signage from the Welsh Assembly”){:rel=”external”}

The generated link is:

 <a href="http://new.wales.gov.uk/smokingbanwalessub/home/guidance/signage/signage/?lang=en%20%E2%80%9CBilingual%20No%20Smoking%20signage%20from%20the%20Welsh%20Assembly%E2%80%9D">bilingual signs</a>

Note that the original markdown uses smart quotes - is this the problem? If I replace them with normal double quotes the link works as expected and gives me:

 <a href="http://new.wales.gov.uk/smokingbanwalessub/home/guidance/signage/signage/?lang=en" title="Bilingual No Smoking signage from the Welsh Assembly" rel="external">bilingual signs</a>

So I guess the issue is one of:

  • Should the parser also recognise smart quotes
  • Is it an error in the original source?

Merge cells in Govspeak tables

There isn't currently a way to merge cells in tables in Govspeak. I'm working on a piece of content that includes a lot of tables. A few of them have data that applies to multiple columns, so it would be useful if I could merge cells across the table.

I've attached screenshots of how one such table looks in Google Docs and how it looks when translated into Govspeak and published on GOV.UK.

As you can see, I've had to split this into 2 smaller tables as a workaround. I'm concerned this could lead to the information being misinterpreted by users. For example, users might think they only need to do the checks listed in one of the tables - not both.

Can someone please look into this? Thanks 🙂

Screenshot 2020-07-21 at 12 37 43

Screenshot 2020-07-21 at 12 37 33

URI Gotcha with Ruby 2.2.x

Applications using this gem need to take care when upgrading to Ruby 2.2.x as it is less tolerant of non-standard URIs and so new and existing content might no longer be parseable by Govspeak.

More detail:

Ruby 2.2 upgrades the URI module in stdlib to support RFC3986. This is a stricter form of URI.parse and means that anywhere we parse URIs that might be invalid, an error will be raised.

Examples found so far include:

  • mailto://address links (raises NoMethodError: undefined method 'split' for nil:NilClass
  • blank mailto: (raises NoMethodError: undefined method 'split' for nil:NilClass)
  • URLs with trailing spaces (raises URI::InvalidURIError: bad URI(is not URI?))

This may or may not be something we can/should fix in Govspeak. The alternative is to be aware when upgrading apps using Govspeak to fix existing content.

@boffbowsh did the hard work to figure this out. For more information, see: alphagov/whitehall#2234

Rendering hangs on some malformed govspeak

Rendering the following malformed govspeak string hangs for ages before failing altogether. It would be more helpful to quickly return an error.

govspeak = <<-END_GOVSPEAK               
$LegislativeList                         
* Item                                   
  $EndLegislativeList                    
END_GOVSPEAK                             
Govspeak::Document.new(govspeak).to_html 

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.