diff --git a/site/_includes/example.html b/site/_includes/example.html deleted file mode 100644 index d2f8182d680b..000000000000 --- a/site/_includes/example.html +++ /dev/null @@ -1,23 +0,0 @@ -{%- comment -%} -Usage: {% include example.html content=markup %}, -where content is a capture with the HTML content -id - null (default) -class - "bd-example" (default) -optional: hide_preview - disabled (default) -optional: hide_markup - disabled (default) -{%- endcomment -%} - -{%- assign preview_id = include.id -%} -{%- assign preview_class = include.class -%} - -{%- if include.hide_preview == null -%} - - {{- include.content -}} - -{%- endif -%} - -{%- if include.hide_markup == null -%} - {%- highlight html -%} - {{- include.content | replace: 'data-src="holder.js', 'src="...' -}} - {%- endhighlight -%} -{%- endif -%} diff --git a/site/_plugins/example.rb b/site/_plugins/example.rb new file mode 100644 index 000000000000..913289720629 --- /dev/null +++ b/site/_plugins/example.rb @@ -0,0 +1,95 @@ +module Jekyll + module Tags + class ExampleBlock < Liquid::Block + include Liquid::StandardFilters + + # The regular expression syntax checker. Start with the language specifier. + # Follow that by zero or more space separated options that take one of three + # forms: name, name=value, or name="" + # + # is a space-separated list of numbers + SYNTAX = /^([a-zA-Z0-9.+#-]+)((\s+\w+(=((\w|[0-9_-])+|"([0-9]+\s)*[0-9]+"))?)*)$/ + + def initialize(tag_name, markup, tokens) + super + if markup.strip =~ SYNTAX + @lang = $1.downcase + @options = {} + if defined?($2) && $2 != '' + # Split along 3 possible forms -- key="", key=value, or key + $2.scan(/(?:\w+(?:=(?:(?:\w|[0-9_-])+|"[^"]*")?)?)/) do |opt| + key, value = opt.split('=') + # If a quoted list, convert to array + if value && value.include?("\"") + value.gsub!(/"/, "") + value = value.split + end + @options[key.to_sym] = value || true + end + end + @options[:linenos] = false + else + raise SyntaxError.new <<-eos +Syntax Error in tag 'example' while parsing the following markup: + + #{markup} + +Valid syntax: example [id=foo] +eos + end + end + + def render(context) + prefix = context["highlighter_prefix"] || "" + suffix = context["highlighter_suffix"] || "" + code = super.to_s.strip + + output = case context.registers[:site].highlighter + + when 'rouge' + render_rouge(code) + end + + rendered_output = example(code) + add_code_tag(output) + prefix + rendered_output + suffix + end + + def example(output) + "
\n#{output}\n
" + end + + def remove_holderjs(code) + code = code.gsub(/data-src="holder.js.+?"/, 'src="..."') + end + + def remove_example_classes(code) + # Find `bd-` classes and remove them from the highlighted code. Because of how this regex works, it will also + # remove classes that are after the `bd-` class. While this is a bug, I left it because it can be helpful too. + # To fix the bug, replace `(?=")` with `(?=("|\ ))`. + code = code.gsub(/(?!class=".)\ *?bd-.+?(?=")/, "") + # Find empty class attributes after the previous regex and remove those too. + code = code.gsub(/\ class=""/, "") + end + + def render_rouge(code) + require 'rouge' + formatter = Rouge::Formatters::HTML.new(line_numbers: @options[:linenos], wrap: false) + lexer = Rouge::Lexer.find_fancy(@lang, code) || Rouge::Lexers::PlainText + code = remove_holderjs(code) + code = remove_example_classes(code) + code = formatter.format(lexer.lex(code)) + "
#{code}
" + end + + def add_code_tag(code) + # Add nested tags to code blocks + code = code.sub(/
\n*/,'
')
+        code = code.sub(/\n*<\/pre>/,"
") + code.strip + end + + end + end +end + +Liquid::Template.register_tag('example', Jekyll::Tags::ExampleBlock) diff --git a/site/docs/4.1/components/alerts.md b/site/docs/4.1/components/alerts.md index 6c6cb993663f..54739990eb6a 100644 --- a/site/docs/4.1/components/alerts.md +++ b/site/docs/4.1/components/alerts.md @@ -10,13 +10,12 @@ toc: true Alerts are available for any length of text, as well as an optional dismiss button. For proper styling, use one of the eight **required** contextual classes (e.g., `.alert-success`). For inline dismissal, use the [alerts jQuery plugin](#dismissing). -{% capture example %} +{% example html %} {% for color in site.data.theme-colors %} {% endfor %} -{% endcapture %} -{% include example.html content=example %} +{% endexample %} {% include callout-warning-color-assistive-technologies.md %} @@ -24,27 +23,25 @@ Alerts are available for any length of text, as well as an optional dismiss butt Use the `.alert-link` utility class to quickly provide matching colored links within any alert. -{% capture example %} +{% example html %} {% for color in site.data.theme-colors %} {% endfor %} -{% endcapture %} -{% include example.html content=example %} +{% endexample %} ### Additional content Alerts can also contain additional HTML elements like headings, paragraphs and dividers. -{% capture example %} +{% example html %} -{% endcapture %} -{% include example.html content=example %} +{% endexample %} ### Dismissing @@ -59,15 +56,14 @@ Using the alert JavaScript plugin, it's possible to dismiss any alert inline. He You can see this in action with a live demo: -{% capture example %} +{% example html %} -{% endcapture %} -{% include example.html content=example %} +{% endexample %} ## JavaScript behavior diff --git a/site/docs/4.1/components/badge.md b/site/docs/4.1/components/badge.md index 0e97cbe76305..f8967921e092 100644 --- a/site/docs/4.1/components/badge.md +++ b/site/docs/4.1/components/badge.md @@ -30,34 +30,31 @@ Badges scale to match the size of the immediate parent element by using relative Badges can be used as part of links or buttons to provide a counter. -{% capture example %} +{% example html %} -{% endcapture %} -{% include example.html content=example %} +{% endexample %} Note that depending on how they are used, badges may be confusing for users of screen readers and similar assistive technologies. While the styling of badges provides a visual cue as to their purpose, these users will simply be presented with the content of the badge. Depending on the specific situation, these badges may seem like random additional words or numbers at the end of a sentence, link, or button. Unless the context is clear (as with the "Notifications" example, where it is understood that the "4" is the number of notifications), consider including additional context with a visually hidden piece of additional text. -{% capture example %} +{% example html %} -{% endcapture %} -{% include example.html content=example %} +{% endexample %} ## Contextual variations Add any of the below mentioned modifier classes to change the appearance of a badge. -{% capture example %} +{% example html %} {% for color in site.data.theme-colors %} {{ color.name | capitalize }}{% endfor %} -{% endcapture %} -{% include example.html content=example %} +{% endexample %} {% include callout-warning-color-assistive-technologies.md %} @@ -65,18 +62,16 @@ Add any of the below mentioned modifier classes to change the appearance of a ba Use the `.badge-pill` modifier class to make badges more rounded (with a larger `border-radius` and additional horizontal `padding`). Useful if you miss the badges from v3. -{% capture example %} +{% example html %} {% for color in site.data.theme-colors %} {{ color.name | capitalize }}{% endfor %} -{% endcapture %} -{% include example.html content=example %} +{% endexample %} ## Links Using the contextual `.badge-*` classes on an `` element quickly provide _actionable_ badges with hover and focus states. -{% capture example %} +{% example html %} {% for color in site.data.theme-colors %} {{ color.name | capitalize }}{% endfor %} -{% endcapture %} -{% include example.html content=example %} +{% endexample %} diff --git a/site/docs/4.1/components/breadcrumb.md b/site/docs/4.1/components/breadcrumb.md index 0837e83633da..35bbd8d0a02f 100644 --- a/site/docs/4.1/components/breadcrumb.md +++ b/site/docs/4.1/components/breadcrumb.md @@ -7,7 +7,7 @@ group: components ## Example -{% capture example %} +{% example html %} -{% endcapture %} -{% include example.html content=example %} +{% endexample %} ## Changing the separator diff --git a/site/docs/4.1/components/button-group.md b/site/docs/4.1/components/button-group.md index 2261a5e7294f..f02ded31b442 100644 --- a/site/docs/4.1/components/button-group.md +++ b/site/docs/4.1/components/button-group.md @@ -10,14 +10,13 @@ toc: true Wrap a series of buttons with `.btn` in `.btn-group`. Add on optional JavaScript radio and checkbox style behavior with [our buttons plugin]({{ site.baseurl }}/docs/{{ site.docs_version }}/components/buttons/#button-plugin). -{% capture example %} +{% example html %}
-{% endcapture %} -{% include example.html content=example %} +{% endexample %} {% capture callout %} ##### Ensure correct `role` and provide a label @@ -32,7 +31,7 @@ In addition, groups and toolbars should be given an explicit label, as most assi Combine sets of button groups into button toolbars for more complex components. Use utility classes as needed to space out groups, buttons, and more. -{% capture example %} +{% example html %} -{% endcapture %} -{% include example.html content=example %} +{% endexample %} Feel free to mix input groups with button groups in your toolbars. Similar to the example above, you'll likely need some utilities though to space things properly. -{% capture example %} +{% example html %} -{% endcapture %} -{% include example.html content=example %} +{% endexample %} ## Sizing @@ -121,7 +118,7 @@ Instead of applying button sizing classes to every button in a group, just add ` Place a `.btn-group` within another `.btn-group` when you want dropdown menus mixed with a series of buttons. -{% capture example %} +{% example html %}
@@ -136,8 +133,7 @@ Place a `.btn-group` within another `.btn-group` when you want dropdown menus mi
-{% endcapture %} -{% include example.html content=example %} +{% endexample %} ## Vertical variation diff --git a/site/docs/4.1/components/buttons.md b/site/docs/4.1/components/buttons.md index f999fd552eed..e64fd675467f 100644 --- a/site/docs/4.1/components/buttons.md +++ b/site/docs/4.1/components/buttons.md @@ -11,13 +11,12 @@ toc: true Bootstrap includes several predefined button styles, each serving its own semantic purpose, with a few extras thrown in for more control. -{% capture example %} +{% example html %} {% for color in site.data.theme-colors %} {% endfor %} -{% endcapture %} -{% include example.html content=example %} +{% endexample %} {% include callout-warning-color-assistive-technologies.md %} @@ -27,68 +26,61 @@ The `.btn` classes are designed to be used with the ` -{% endcapture %} -{% include example.html content=example %} +{% endexample %} ## Outline buttons In need of a button, but not the hefty background colors they bring? Replace the default modifier classes with the `.btn-outline-*` ones to remove all background images and colors on any button. -{% capture example %} +{% example html %} {% for color in site.data.theme-colors %} {% endfor %} -{% endcapture %} -{% include example.html content=example %} +{% endexample %} ## Sizes Fancy larger or smaller buttons? Add `.btn-lg` or `.btn-sm` for additional sizes. -{% capture example %} +{% example html %} -{% endcapture %} -{% include example.html content=example %} +{% endexample %} -{% capture example %} +{% example html %} -{% endcapture %} -{% include example.html content=example %} +{% endexample %} Create block level buttons—those that span the full width of a parent—by adding `.btn-block`. -{% capture example %} +{% example html %} -{% endcapture %} -{% include example.html content=example %} +{% endexample %} ## Active state Buttons will appear pressed (with a darker background, darker border, and inset shadow) when active. **There's no need to add a class to ` -{% endcapture %} -{% include example.html content=example %} +{% endexample %} Disabled buttons using the `` element behave a bit different: @@ -96,11 +88,10 @@ Disabled buttons using the `` element behave a bit different: - Some future-friendly styles are included to disable all `pointer-events` on anchor buttons. In browsers which support that property, you won't see the disabled cursor at all. - Disabled buttons should include the `aria-disabled="true"` attribute to indicate the state of the element to assistive technologies. -{% capture example %} +{% example html %} Primary link Link -{% endcapture %} -{% include example.html content=example %} +{% endexample %} {% capture callout %} ##### Link functionality caveat @@ -117,12 +108,11 @@ Do more with buttons. Control button states or create groups of buttons for more Add `data-toggle="button"` to toggle a button's `active` state. If you're pre-toggling a button, you must manually add the `.active` class **and** `aria-pressed="true"` to the ` -{% endcapture %} -{% include example.html content=example %} +{% endexample %} ### Checkbox and radio buttons @@ -132,16 +122,15 @@ The checked state for these buttons is **only updated via `click` event** on the Note that pre-checked buttons require you to manually add the `.active` class to the input's `