Class: Jekyll::SvgViewer::Tag

Inherits:
Liquid::Tag
  • Object
show all
Includes:
ERB::Util
Defined in:
lib/jekyll/svg_viewer/tag.rb

Constant Summary collapse

ATTRIBUTE_REGEX =
/
  (?<key>[a-zA-Z0-9_]+)
  \s*=\s*
  (?<value>
    "(?:[^"\\]|\\.)*" |
    '(?:[^'\\]|\\.)*' |
    [^\s]+
  )
/x.freeze
ATTR_ALIASES =
{
  "button_bg" => "button_fill",
  "button_background" => "button_fill",
  "button_fg" => "button_foreground",
  "pan" => "pan_mode",
  "zoom_behavior" => "zoom_mode",
  "zoom_interaction" => "zoom_mode",
  "initial_zoom" => "zoom"
}.freeze
BUTTONS =
{
  "zoom_in" => {
    "class" => "zoom-in-btn",
    "icon" => '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640" aria-hidden="true" focusable="false"><path fill="currentColor" d="M480 272C480 317.9 465.1 360.3 440 394.7L566.6 521.4C579.1 533.9 579.1 554.2 566.6 566.7C554.1 579.2 533.8 579.2 521.3 566.7L394.7 440C360.3 465.1 317.9 480 272 480C157.1 480 64 386.9 64 272C64 157.1 157.1 64 272 64C386.9 64 480 157.1 480 272zM272 176C258.7 176 248 186.7 248 200L248 248L200 248C186.7 248 176 258.7 176 272C176 285.3 186.7 296 200 296L248 296L248 344C248 357.3 258.7 368 272 368C285.3 368 296 357.3 296 344L296 296L344 296C357.3 296 368 285.3 368 272C368 258.7 357.3 248 344 248L296 248L296 200C296 186.7 285.3 176 272 176z"/></svg>',
    "text" => "Zoom In",
    "title" => "Zoom In (Ctrl +)",
    "requires_show_coords" => false
  },
  "zoom_out" => {
    "class" => "zoom-out-btn",
    "icon" => '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640" aria-hidden="true" focusable="false"><path fill="currentColor" d="M480 272C480 317.9 465.1 360.3 440 394.7L566.6 521.4C579.1 533.9 579.1 554.2 566.6 566.7C554.1 579.2 533.8 579.2 521.3 566.7L394.7 440C360.3 465.1 317.9 480 272 480C157.1 480 64 386.9 64 272C64 157.1 157.1 64 272 64C386.9 64 480 157.1 480 272zM200 248C186.7 248 176 258.7 176 272C176 285.3 186.7 296 200 296L344 296C357.3 296 368 285.3 368 272C368 258.7 357.3 248 344 248L200 248z"/></svg>',
    "text" => "Zoom Out",
    "title" => "Zoom Out (Ctrl -)",
    "requires_show_coords" => false
  },
  "reset" => {
    "class" => "reset-zoom-btn",
    "icon" => '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640" aria-hidden="true" focusable="false"><path fill="currentColor" d="M480 272C480 317.9 465.1 360.3 440 394.7L566.6 521.4C579.1 533.9 579.1 554.2 566.6 566.7C554.1 579.2 533.8 579.2 521.3 566.7L394.7 440C360.3 465.1 317.9 480 272 480C157.1 480 64 386.9 64 272C64 157.1 157.1 64 272 64C386.9 64 480 157.1 480 272zM272 416C351.5 416 416 351.5 416 272C416 192.5 351.5 128 272 128C192.5 128 128 192.5 128 272C128 351.5 192.5 416 272 416z"/></svg>',
    "text" => "Reset Zoom",
    "title" => "Reset Zoom",
    "requires_show_coords" => false
  },
  "center" => {
    "class" => "center-view-btn",
    "icon" => '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640" aria-hidden="true" focusable="false"><path fill="currentColor" d="M320 48C337.7 48 352 62.3 352 80L352 98.3C450.1 112.3 527.7 189.9 541.7 288L560 288C577.7 288 592 302.3 592 320C592 337.7 577.7 352 560 352L541.7 352C527.7 450.1 450.1 527.7 352 541.7L352 560C352 577.7 337.7 592 320 592C302.3 592 288 577.7 288 560L288 541.7C189.9 527.7 112.3 450.1 98.3 352L80 352C62.3 352 48 337.7 48 320C48 302.3 62.3 288 80 288L98.3 288C112.3 189.9 189.9 112.3 288 98.3L288 80C288 62.3 302.3 48 320 48zM163.2 352C175.9 414.7 225.3 464.1 288 476.8L288 464C288 446.3 302.3 432 320 432C337.7 432 352 446.3 352 464L352 476.8C414.7 464.1 464.1 414.7 476.8 352L464 352C446.3 352 432 337.7 432 320C432 302.3 446.3 288 464 288L476.8 288C464.1 225.3 414.7 175.9 352 163.2L352 176C352 193.7 337.7 208 320 208C302.3 208 288 193.7 288 176L288 163.2C225.3 175.9 175.9 225.3 163.2 288L176 288C193.7 288 208 302.3 208 320C208 337.7 193.7 352 176 352L163.2 352zM320 272C346.5 272 368 293.5 368 320C368 346.5 346.5 368 320 368C293.5 368 272 346.5 272 320C272 293.5 293.5 272 320 272z"/></svg>',
    "text" => "Center View",
    "title" => "Center View",
    "requires_show_coords" => false
  },
  "coords" => {
    "class" => "coord-copy-btn",
    "icon" => "📍",
    "text" => "Copy Center",
    "title" => "Copy current center coordinates",
    "requires_show_coords" => true
  }
}.freeze
MODE_OPTIONS =
%w[icon text both].freeze
STYLE_OPTIONS =
%w[compact labels-on-hover labels_on_hover].freeze
HIDDEN_OPTIONS =
%w[hidden none].freeze
ALIGNMENT_OPTIONS =
%w[alignleft aligncenter alignright].freeze
AVAILABLE_BUTTONS =
BUTTONS.keys.freeze

Instance Method Summary collapse

Constructor Details

#initialize(tag_name, markup, tokens) ⇒ Tag



74
75
76
77
# File 'lib/jekyll/svg_viewer/tag.rb', line 74

def initialize(tag_name, markup, tokens)
  super
  @raw_markup = markup.to_s
end

Instance Method Details

#render(context) ⇒ Object



79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
# File 'lib/jekyll/svg_viewer/tag.rb', line 79

def render(context)
  site = context.registers[:site]
  page = context.registers[:page]
  config = Config.for(site)

  attrs = merge_defaults(config["defaults"], parse_attributes(@raw_markup))
  attrs["show_coords"] = truthy?(attrs["show_coords"])

  validate_src!(attrs["src"])

  viewer_id = "svg-viewer-#{SecureRandom.hex(6)}"

  zoom_values = normalize_zoom_values(attrs)
  interaction = resolve_interaction(attrs["pan_mode"], attrs["zoom_mode"])
  controls = parse_controls_config(attrs["controls_position"], attrs["controls_buttons"], attrs["show_coords"])
  controls_markup = render_controls_markup(
    viewer_id,
    controls,
    zoom_values[:initial_percent],
    zoom_values[:min_percent],
    zoom_values[:max_percent],
    zoom_values[:step_percent]
  )

  wrapper_classes = build_wrapper_classes(attrs, controls, interaction)
  main_classes = main_container_classes(controls)
  wrapper_style = build_wrapper_style(attrs)

  AssetManager.flag_page_for_assets(site, page)

  interaction_caption = interaction[:messages].empty? ? "" : %(<div class="svg-viewer-caption svg-viewer-interaction-caption">#{interaction[:messages].map { |m| h(m) }.join("<br />")}</div>)
  caption_markup = caption_html(attrs["caption"])
  title_markup = title_html(attrs["title"])

  "    <div id=\"\#{viewer_id}\" class=\"\#{wrapper_classes}\" style=\"\#{wrapper_style}\">\n      \#{title_markup}\n      <div class=\"\#{main_classes}\">\n        \#{controls_markup}\n        <div class=\"svg-container\" style=\"height: \#{h(attrs['height'])}; width: 100%; max-width: 100%; min-width: 0;\" data-viewer=\"\#{viewer_id}\">\n          <div class=\"svg-viewport\" data-viewer=\"\#{viewer_id}\"></div>\n        </div>\n      </div>\n      \#{interaction_caption}\n      \#{caption_markup}\n    </div>\n    \#{viewer_bootstrap(viewer_id, attrs, zoom_values, interaction, controls, site)}\n  HTML\nend\n"