marker icon indicating copy to clipboard operation
marker copied to clipboard

Add a .formatter.exs to export the DSL macros as locals without parens

Open ejpcmac opened this issue 7 years ago • 5 comments

Since v1.6, Elixir features a code formatter. By default, it add parentheses to all functions or macro calls. The first Marker sample code would look like this once formatted:

use Marker.HTML

name = "Vincent"

html do
  body do
    div do
      h3("Person")
      p(name, class: "name")
      p(2 * 19, class: "age")
    end
  end
end

It is however possible to declare locals_without_parens in a .formatter.exs to avoid this behaviour for DSL macros. For libraries like Marker, it is possible to export such configurations and import them in the user’s projects.

We should export all the Marker DSL macros as locals_without_parens.

ejpcmac avatar Feb 04 '18 12:02 ejpcmac

That would be a good idea and could be generated at compile time for all the default elements (imported with use Marker.HTML)

The place to look into would be Marker.Element.__using__/1 or Marker.Element.def_element/2

zambal avatar Feb 05 '18 12:02 zambal

I haven't an idea how to automatically add user defined components though. Maybe we should leave that up to users and let them add the needed configuration in their project.

zambal avatar Feb 05 '18 12:02 zambal

If you need any guidance with understanding what's happening inside Marker.Element.__using__/1 or Marker.Element.def_element/2, let me know.

zambal avatar Feb 05 '18 12:02 zambal

Sorry for not replying, my bandwidth is quite limited this week. I put this on my pipeline for when I’ll try Marker, maybe in a week or two.

ejpcmac avatar Feb 07 '18 18:02 ejpcmac

I added this to my formatter.ex but used the code below and wondering if it would work dynamically somehow to compile this ahead of time so it's avaialable to export from formatter.ex

is_macro? = fn {k, _} ->
  k
  |> Atom.to_string()
  |> String.starts_with?("MACRO")
end

replace_macro = fn {k, v} -> 
  new_k = k
  |> Atom.to_string()
  |> String.replace("MACRO-", "")
  |> String.to_atom()
  {new_k, v}
end

names = Marker.HTML.module_info(:functions)
|> Enum.filter(is_macro?)
|> Enum.map(replace_macro)
|> IO.inspect(limit: :infinity)

locals_without_parens = [
  a: 1, a: 2, a: 3,
  abbr: 1, abbr: 2, abbr: 3,
  address: 1, address: 2, address: 3,
  area: 1, area: 2, area: 3,
  article: 1, article: 2, article: 3,
  aside: 1, aside: 2, aside: 3,
  audio: 1, audio: 2, audio: 3,
  b: 1, b: 2, b: 3,
  base: 1, base: 2, base: 3,
  bdi: 1, bdi: 2, bdi: 3,
  bdo: 1, bdo: 2, bdo: 3,
  blockquote: 1, blockquote: 2, blockquote: 3,
  body: 1, body: 2, body: 3,
  br: 1, br: 2, br: 3,
  button: 1, button: 2, button: 3,
  canvas: 1, canvas: 2, canvas: 3,
  caption: 1, caption: 2, caption: 3,
  cite: 1, cite: 2, cite: 3,
  code: 1, code: 2, code: 3,
  col: 1, col: 2, col: 3,
  colgroup: 1, colgroup: 2, colgroup: 3,
  content: 1, content: 2, content: 3,
  data: 1, data: 2, data: 3,
  datalist: 1, datalist: 2, datalist: 3,
  dd: 1, dd: 2, dd: 3,
  del: 1, del: 2, del: 3,
  details: 1, details: 2, details: 3,
  dfn: 1, dfn: 2, dfn: 3,
  div: 1, div: 2, div: 3,
  dl: 1, dl: 2, dl: 3,
  dt: 1, dt: 2, dt: 3,
  em: 1, em: 2, em: 3,
  embed: 1, embed: 2, embed: 3,
  fieldset: 1, fieldset: 2, fieldset: 3,
  figcaption: 1, figcaption: 2, figcaption: 3,
  figure: 1, figure: 2, figure: 3,
  footer: 1, footer: 2, footer: 3,
  form: 1, form: 2, form: 3,
  h1: 1, h1: 2, h1: 3,
  h2: 1, h2: 2, h2: 3,
  h3: 1, h3: 2, h3: 3,
  h4: 1, h4: 2, h4: 3,
  h5: 1, h5: 2, h5: 3,
  h6: 1, h6: 2, h6: 3,
  head: 1, head: 2, head: 3,
  header: 1, header: 2, header: 3,
  hr: 1, hr: 2, hr: 3,
  html: 1, html: 2, html: 3,
  i: 1, i: 2, i: 3,
  iframe: 1, iframe: 2, iframe: 3,
  img: 1, img: 2, img: 3,
  input: 1, input: 2, input: 3,
  ins: 1, ins: 2, ins: 3,
  kbd: 1, kbd: 2, kbd: 3,
  keygen: 1, keygen: 2, keygen: 3,
  label: 1, label: 2, label: 3,
  legend: 1, legend: 2, legend: 3,
  li: 1, li: 2, li: 3,
  link: 1, link: 2, link: 3,
  main: 1, main: 2, main: 3,
  map: 1, map: 2, map: 3,
  mark: 1, mark: 2, mark: 3,
  menu: 1, menu: 2, menu: 3,
  menuitem: 1, menuitem: 2, menuitem: 3,
  meta: 1, meta: 2, meta: 3,
  meter: 1, meter: 2, meter: 3,
  nav: 1, nav: 2, nav: 3,
  noscript: 1, noscript: 2, noscript: 3,
  object: 1, object: 2, object: 3,
  ol: 1, ol: 2, ol: 3,
  optgroup: 1, optgroup: 2, optgroup: 3,
  option: 1, option: 2, option: 3,
  output: 1, output: 2, output: 3,
  p: 1, p: 2, p: 3,
  param: 1, param: 2, param: 3,
  pre: 1, pre: 2, pre: 3,
  progress: 1, progress: 2, progress: 3,
  q: 1, q: 2, q: 3,
  rp: 1, rp: 2, rp: 3,
  rt: 1, rt: 2, rt: 3,
  ruby: 1, ruby: 2, ruby: 3,
  s: 1, s: 2, s: 3,
  samp: 1, samp: 2, samp: 3,
  script: 1, script: 2, script: 3,
  section: 1, section: 2, section: 3,
  select: 1, select: 2, select: 3,
  shadow: 1, shadow: 2, shadow: 3,
  small: 1, small: 2, small: 3,
  source: 1, source: 2, source: 3,
  span: 1, span: 2, span: 3,
  string: 1, string: 2, string: 3,
  style: 1, style: 2, style: 3,
  sub: 1, sub: 2, sub: 3,
  summary: 1, summary: 2, summary: 3,
  sup: 1, sup: 2, sup: 3,
  table: 1, table: 2, table: 3,
  tbody: 1, tbody: 2, tbody: 3,
  td: 1, td: 2, td: 3,
  template: 1, template: 2, template: 3,
  textarea: 1, textarea: 2, textarea: 3,
  tfoot: 1, tfoot: 2, tfoot: 3,
  th: 1, th: 2, th: 3,
  thead: 1, thead: 2, thead: 3,
  time: 1, time: 2, time: 3,
  title: 1, title: 2, title: 3,
  tr: 1, tr: 2, tr: 3,
  track: 1, track: 2, track: 3,
  u: 1, u: 2, u: 3,
  ul: 1, ul: 2, ul: 3,
  var: 1, var: 2, var: 3,
  video: 1, video: 2, video: 3,
  wbr: 1, wbr: 2, wbr: 3,
  xmp: 1, xmp: 2, xmp: 3
]

dantheobserver avatar Jan 02 '23 16:01 dantheobserver