[DRE-commits] [ruby-org] 55/303: Everything now shows up in code blocks, even org-mode metadata.
Jérémy Bobbio
lunar at alioth.debian.org
Fri Aug 9 17:33:26 UTC 2013
This is an automated email from the git hooks/post-receive script.
lunar pushed a commit to branch master
in repository ruby-org.
commit 33bcfafe7c7ee2c9714616cde88b6fe46c9124cf
Author: Brian Dewey <bdewey at gmail.com>
Date: Tue Dec 29 11:22:51 2009 -0800
Everything now shows up in code blocks, even org-mode metadata.
---
History.txt | 1 +
TAGS | 261 ++++++++++----------
lib/org-ruby/line.rb | 45 +++-
lib/org-ruby/parser.rb | 34 ++-
...data-comment.org-fail => metadata-comment.html} | 12 +-
...adata-comment.org-fail => metadata-comment.org} | 0
6 files changed, 201 insertions(+), 152 deletions(-)
diff --git a/History.txt b/History.txt
index 8a7eb58..90bc2d2 100644
--- a/History.txt
+++ b/History.txt
@@ -1,5 +1,6 @@
== X.X.X / 2009-12-29
+* Everything now shows up in code blocks, even org-mode metadata.
* Fixed bugs:
* Regressed smart double quotes with HTML escaping. Added a test
case and fixed the regression.
diff --git a/TAGS b/TAGS
index fddf4f2..4167666 100644
--- a/TAGS
+++ b/TAGS
@@ -1,128 +1,133 @@
-
-./spec/parser_spec.rb,0
-
-./spec/headline_spec.rb,0
-
-./spec/line_spec.rb,0
-
-./spec/spec_helper.rb,0
-
-./spec/regexp_helper_spec.rb,0
-
-./spec/textile_output_buffer_spec.rb,0
-
-./lib/org-ruby.rb,242
-module OrgRuby::OrgRuby2,1
- def self.version::OrgRuby.version12,251
- def self.libpath::OrgRuby.libpath20,450
- def self.path::OrgRuby.path28,695
- def self.require_all_libs_relative_to::OrgRuby.require_all_libs_relative_to37,1082
-
-./lib/org-ruby/html_output_buffer.rb,349
-module Orgmode::Orgmode3,54
- class HtmlOutputBuffer::Orgmode::HtmlOutputBuffer5,72
- def push_mode::Orgmode::HtmlOutputBuffer#push_mode22,417
- def pop_mode::Orgmode::HtmlOutputBuffer#pop_mode27,525
- def flush!::Orgmode::HtmlOutputBuffer#flush!32,647
- def inline_formatting::Orgmode::HtmlOutputBuffer#inline_formatting62,1689
-
-./lib/org-ruby/output_buffer.rb,1195
-module Orgmode::Orgmode3,18
- class OutputBuffer::Orgmode::OutputBuffer9,297
- attr_reader :buffer::Orgmode::OutputBuffer#buffer12,381
- attr_reader :output::Orgmode::OutputBuffer#output15,446
- attr_accessor :output_type::Orgmode::OutputBuffer#output_type18,532
- def initialize::Orgmode::OutputBuffer#Orgmode::OutputBuffer.new22,686
- def current_mode::Orgmode::OutputBuffer#current_mode40,1138
- def current_mode_list?::Orgmode::OutputBuffer#current_mode_list?44,1197
- def push_mode::Orgmode::OutputBuffer#push_mode48,1286
- def pop_mode::Orgmode::OutputBuffer#pop_mode53,1421
- def prepare::Orgmode::OutputBuffer#prepare61,1729
- def enter_table?::Orgmode::OutputBuffer#enter_table?73,2129
- def exit_table?::Orgmode::OutputBuffer#exit_table?79,2314
- def <<::Orgmode::OutputBuffer#<<85,2480
- def list_indent_level::Orgmode::OutputBuffer#list_indent_level90,2585
- def preserve_whitespace?::Orgmode::OutputBuffer#preserve_whitespace?95,2729
- def maintain_list_indent_stack::Orgmode::OutputBuffer#maintain_list_indent_stack102,2866
- def should_accumulate_output?::Orgmode::OutputBuffer#should_accumulate_output?127,3724
-
-./lib/org-ruby/headline.rb,619
-module Orgmode::Orgmode3,45
- class Headline::Orgmode::Headline6,109
- attr_reader :level::Orgmode::Headline#level9,178
- attr_reader :headline_text::Orgmode::Headline#headline_text13,325
- attr_reader :body_lines::Orgmode::Headline#body_lines16,418
- attr_reader :tags::Orgmode::Headline#tags19,481
- attr_reader :keyword::Orgmode::Headline#keyword22,567
- def initialize::Orgmode::Headline#Orgmode::Headline.new35,896
- def self.headline?::Orgmode::Headline.headline?58,1687
- def to_textile::Orgmode::Headline#to_textile63,1818
- def to_html::Orgmode::Headline#to_html69,1950
-
-./lib/org-ruby/regexp_helper.rb,1014
-module Orgmode::Orgmode3,18
- class RegexpHelper::Orgmode::RegexpHelper17,456
- attr_reader :pre_emphasis::Orgmode::RegexpHelper#pre_emphasis42,1785
- attr_reader :post_emphasis::Orgmode::RegexpHelper#post_emphasis43,1817
- attr_reader :border_forbidden::Orgmode::RegexpHelper#border_forbidden44,1850
- attr_reader :body_regexp::Orgmode::RegexpHelper#body_regexp45,1886
- attr_reader :markers::Orgmode::RegexpHelper#markers46,1917
- attr_reader :org_emphasis_regexp::Orgmode::RegexpHelper#org_emphasis_regexp48,1945
- def initialize::Orgmode::RegexpHelper#Orgmode::RegexpHelper.new50,1999
- def match_all::Orgmode::RegexpHelper#match_all65,2476
- def rewrite_emphasis::Orgmode::RegexpHelper#rewrite_emphasis92,3413
- def rewrite_links::Orgmode::RegexpHelper#rewrite_links124,4523
- def build_org_emphasis_regexp::Orgmode::RegexpHelper#build_org_emphasis_regexp135,4759
- def build_org_link_regexp::Orgmode::RegexpHelper#build_org_link_regexp145,5326
-
-./lib/org-ruby/textile_output_buffer.rb,454
-module Orgmode::Orgmode3,20
- class TextileOutputBuffer::Orgmode::TextileOutputBuffer5,38
- def initialize::Orgmode::TextileOutputBuffer#Orgmode::TextileOutputBuffer.new7,84
- def push_mode::Orgmode::TextileOutputBuffer#push_mode12,169
- def pop_mode::Orgmode::TextileOutputBuffer#pop_mode17,262
- def inline_formatting::Orgmode::TextileOutputBuffer#inline_formatting34,585
- def flush!::Orgmode::TextileOutputBuffer#flush!48,973
-
-./lib/org-ruby/parser.rb,471
-module Orgmode::Orgmode5,61
- class Parser::Orgmode::Parser7,79
- attr_reader :lines::Orgmode::Parser#lines10,140
- attr_reader :headlines::Orgmode::Parser#headlines13,207
- attr_reader :header_lines::Orgmode::Parser#header_lines16,287
- def initialize::Orgmode::Parser#Orgmode::Parser.new20,459
- def self.load::Orgmode::Parser.load48,1267
- def to_textile::Orgmode::Parser#to_textile54,1433
- def to_html::Orgmode::Parser#to_html63,1620
-
-./lib/org-ruby/line.rb,1430
-module Orgmode::Orgmode1,0
- class Line::Orgmode::Line4,67
- attr_reader :line::Orgmode::Line#line7,114
- attr_reader :indent::Orgmode::Line#indent12,300
- def initialize::Orgmode::Line#Orgmode::Line.new14,325
- def to_s::Orgmode::Line#to_s21,465
- def comment?::Orgmode::Line#comment?26,546
- def metadata?::Orgmode::Line#metadata?31,663
- def nonprinting?::Orgmode::Line#nonprinting?35,755
- def blank?::Orgmode::Line#blank?39,807
- def plain_list?::Orgmode::Line#plain_list?43,859
- def unordered_list?::Orgmode::Line#unordered_list?49,974
- def strip_unordered_list_tag::Orgmode::Line#strip_unordered_list_tag53,1051
- def ordered_list?::Orgmode::Line#ordered_list?59,1168
- def strip_ordered_list_tag::Orgmode::Line#strip_ordered_list_tag63,1241
- def plain_text?::Orgmode::Line#plain_text?67,1309
- def table_row?::Orgmode::Line#table_row?71,1392
- def table_separator?::Orgmode::Line#table_separator?77,1539
- def table?::Orgmode::Line#table?85,1775
- def begin_block?::Orgmode::Line#begin_block?91,1888
- def end_block?::Orgmode::Line#end_block?95,1960
- def block_type::Orgmode::Line#block_type99,2030
- def paragraph_type::Orgmode::Line#paragraph_type104,2152
- def self.to_textile::Orgmode::Line.to_textile115,2470
- def self.to_html::Orgmode::Line.to_html121,2620
- def self.translate::Orgmode::Line.translate128,2816
-
-./bin/org-ruby,0
-
-./test/test_orgmode_parser.rb,0
+
+./bin/org-ruby,0
+
+./lib/org-ruby/headline.rb,619
+module Orgmode::Orgmode3,45
+ class Headline::Orgmode::Headline6,109
+ attr_reader :level::Orgmode::Headline#level9,178
+ attr_reader :headline_text::Orgmode::Headline#headline_text13,325
+ attr_reader :body_lines::Orgmode::Headline#body_lines16,418
+ attr_reader :tags::Orgmode::Headline#tags19,481
+ attr_reader :keyword::Orgmode::Headline#keyword22,567
+ def initialize::Orgmode::Headline#Orgmode::Headline.new35,896
+ def self.headline?::Orgmode::Headline.headline?58,1687
+ def to_textile::Orgmode::Headline#to_textile63,1818
+ def to_html::Orgmode::Headline#to_html69,1939
+
+./lib/org-ruby/html_output_buffer.rb,591
+module Orgmode::Orgmode3,54
+ class HtmlOutputBuffer::Orgmode::HtmlOutputBuffer5,72
+ def initialize::Orgmode::HtmlOutputBuffer#Orgmode::HtmlOutputBuffer.new22,417
+ def push_mode::Orgmode::HtmlOutputBuffer#push_mode31,619
+ def pop_mode::Orgmode::HtmlOutputBuffer#pop_mode42,918
+ def flush!::Orgmode::HtmlOutputBuffer#flush!51,1133
+ def escape_buffer!::Orgmode::HtmlOutputBuffer#escape_buffer!78,2163
+ def output_indentation::Orgmode::HtmlOutputBuffer#output_indentation84,2299
+ def inline_formatting::Orgmode::HtmlOutputBuffer#inline_formatting100,2827
+
+./lib/org-ruby/line.rb,1527
+module Orgmode::Orgmode1,0
+ class Line::Orgmode::Line4,67
+ attr_reader :line::Orgmode::Line#line7,114
+ attr_reader :indent::Orgmode::Line#indent12,300
+ attr_accessor :assigned_paragraph_type::Orgmode::Line#assigned_paragraph_type19,664
+ def initialize::Orgmode::Line#Orgmode::Line.new21,708
+ def to_s::Orgmode::Line#to_s29,885
+ def comment?::Orgmode::Line#comment?34,966
+ def metadata?::Orgmode::Line#metadata?39,1083
+ def nonprinting?::Orgmode::Line#nonprinting?43,1175
+ def blank?::Orgmode::Line#blank?47,1227
+ def plain_list?::Orgmode::Line#plain_list?51,1279
+ def unordered_list?::Orgmode::Line#unordered_list?57,1394
+ def strip_unordered_list_tag::Orgmode::Line#strip_unordered_list_tag61,1471
+ def ordered_list?::Orgmode::Line#ordered_list?67,1588
+ def strip_ordered_list_tag::Orgmode::Line#strip_ordered_list_tag71,1661
+ def plain_text?::Orgmode::Line#plain_text?75,1729
+ def table_row?::Orgmode::Line#table_row?79,1812
+ def table_separator?::Orgmode::Line#table_separator?85,1959
+ def table?::Orgmode::Line#table?93,2195
+ def begin_block?::Orgmode::Line#begin_block?99,2308
+ def end_block?::Orgmode::Line#end_block?103,2380
+ def block_type::Orgmode::Line#block_type107,2450
+ def paragraph_type::Orgmode::Line#paragraph_type112,2572
+ def self.to_textile::Orgmode::Line.to_textile124,2956
+ def self.to_html::Orgmode::Line.to_html130,3106
+ def self.translate::Orgmode::Line.translate137,3320
+
+./lib/org-ruby/output_buffer.rb,1282
+module Orgmode::Orgmode3,18
+ class OutputBuffer::Orgmode::OutputBuffer9,297
+ attr_reader :buffer::Orgmode::OutputBuffer#buffer12,381
+ attr_reader :output::Orgmode::OutputBuffer#output15,446
+ attr_accessor :output_type::Orgmode::OutputBuffer#output_type18,532
+ def initialize::Orgmode::OutputBuffer#Orgmode::OutputBuffer.new22,686
+ def current_mode::Orgmode::OutputBuffer#current_mode40,1138
+ def current_mode_list?::Orgmode::OutputBuffer#current_mode_list?44,1197
+ def push_mode::Orgmode::OutputBuffer#push_mode48,1286
+ def pop_mode::Orgmode::OutputBuffer#pop_mode53,1421
+ def prepare::Orgmode::OutputBuffer#prepare61,1729
+ def enter_table?::Orgmode::OutputBuffer#enter_table?73,2129
+ def exit_table?::Orgmode::OutputBuffer#exit_table?79,2314
+ def <<::Orgmode::OutputBuffer#<<85,2480
+ def list_indent_level::Orgmode::OutputBuffer#list_indent_level90,2585
+ def preserve_whitespace?::Orgmode::OutputBuffer#preserve_whitespace?95,2729
+ def continue_current_list?::Orgmode::OutputBuffer#continue_current_list?106,2991
+ def maintain_list_indent_stack::Orgmode::OutputBuffer#maintain_list_indent_stack109,3037
+ def should_accumulate_output?::Orgmode::OutputBuffer#should_accumulate_output?145,4184
+
+./lib/org-ruby/parser.rb,473
+module Orgmode::Orgmode4,40
+ class Parser::Orgmode::Parser10,125
+ attr_reader :lines::Orgmode::Parser#lines13,186
+ attr_reader :headlines::Orgmode::Parser#headlines16,253
+ attr_reader :header_lines::Orgmode::Parser#header_lines19,333
+ def initialize::Orgmode::Parser#Orgmode::Parser.new23,505
+ def self.load::Orgmode::Parser.load73,2075
+ def to_textile::Orgmode::Parser#to_textile79,2241
+ def to_html::Orgmode::Parser#to_html89,2477
+
+./lib/org-ruby/regexp_helper.rb,1014
+module Orgmode::Orgmode3,18
+ class RegexpHelper::Orgmode::RegexpHelper17,456
+ attr_reader :pre_emphasis::Orgmode::RegexpHelper#pre_emphasis42,1785
+ attr_reader :post_emphasis::Orgmode::RegexpHelper#post_emphasis43,1817
+ attr_reader :border_forbidden::Orgmode::RegexpHelper#border_forbidden44,1850
+ attr_reader :body_regexp::Orgmode::RegexpHelper#body_regexp45,1886
+ attr_reader :markers::Orgmode::RegexpHelper#markers46,1917
+ attr_reader :org_emphasis_regexp::Orgmode::RegexpHelper#org_emphasis_regexp48,1945
+ def initialize::Orgmode::RegexpHelper#Orgmode::RegexpHelper.new50,1999
+ def match_all::Orgmode::RegexpHelper#match_all65,2476
+ def rewrite_emphasis::Orgmode::RegexpHelper#rewrite_emphasis92,3413
+ def rewrite_links::Orgmode::RegexpHelper#rewrite_links124,4523
+ def build_org_emphasis_regexp::Orgmode::RegexpHelper#build_org_emphasis_regexp135,4759
+ def build_org_link_regexp::Orgmode::RegexpHelper#build_org_link_regexp145,5326
+
+./lib/org-ruby/textile_output_buffer.rb,454
+module Orgmode::Orgmode3,20
+ class TextileOutputBuffer::Orgmode::TextileOutputBuffer5,38
+ def initialize::Orgmode::TextileOutputBuffer#Orgmode::TextileOutputBuffer.new7,84
+ def push_mode::Orgmode::TextileOutputBuffer#push_mode12,169
+ def pop_mode::Orgmode::TextileOutputBuffer#pop_mode17,262
+ def inline_formatting::Orgmode::TextileOutputBuffer#inline_formatting34,585
+ def flush!::Orgmode::TextileOutputBuffer#flush!48,973
+
+./lib/org-ruby.rb,243
+module OrgRuby::OrgRuby3,27
+ def self.version::OrgRuby.version13,277
+ def self.libpath::OrgRuby.libpath21,476
+ def self.path::OrgRuby.path29,721
+ def self.require_all_libs_relative_to::OrgRuby.require_all_libs_relative_to38,1108
+
+./spec/headline_spec.rb,0
+
+./spec/line_spec.rb,0
+
+./spec/parser_spec.rb,0
+
+./spec/regexp_helper_spec.rb,0
+
+./spec/spec_helper.rb,0
+
+./spec/textile_output_buffer_spec.rb,0
+
+./test/test_orgmode_parser.rb,0
diff --git a/lib/org-ruby/line.rb b/lib/org-ruby/line.rb
index ebb154d..e086acb 100644
--- a/lib/org-ruby/line.rb
+++ b/lib/org-ruby/line.rb
@@ -14,16 +14,16 @@ module Orgmode
# A line can have its type assigned instead of inferred from its
# content. For example, something that parses as a "table" on its
# own ("| one | two|\n") may just be a paragraph if it's inside
- # #+BEGIN_EXAMPLE. Set this property on the line to assign its type. This
- # will then affect the value of +paragraph_type+.
+ # #+BEGIN_EXAMPLE. Set this property on the line to assign its
+ # type. This will then affect the value of +paragraph_type+.
attr_accessor :assigned_paragraph_type
def initialize(line)
@line = line
@indent = 0
@line =~ /\s*/
- @indent = $&.length unless blank?
@assigned_paragraph_type = nil
+ @indent = $&.length unless blank?
end
def to_s
@@ -32,12 +32,12 @@ module Orgmode
# Tests if a line is a comment.
def comment?
- @line =~ /^\s*#/
+ check_assignment_or_regexp(:comment, /^\s*#/)
end
# Tests if a line contains metadata instead of actual content.
def metadata?
- @line =~ /^\s*(CLOCK|DEADLINE|START|CLOSED|SCHEDULED):/
+ check_assignment_or_regexp(:metadata, /^\s*(CLOCK|DEADLINE|START|CLOSED|SCHEDULED):/)
end
def nonprinting?
@@ -45,7 +45,7 @@ module Orgmode
end
def blank?
- @line =~ /^\s*$/
+ check_assignment_or_regexp(:blank, /^\s*$/)
end
def plain_list?
@@ -55,7 +55,7 @@ module Orgmode
UnorderedListRegexp = /^\s*(-|\+)\s*/
def unordered_list?
- @line =~ UnorderedListRegexp
+ check_assignment_or_regexp(:unordered_list, UnorderedListRegexp)
end
def strip_unordered_list_tag
@@ -65,7 +65,7 @@ module Orgmode
OrderedListRegexp = /^\s*\d+(\.|\))\s*/
def ordered_list?
- @line =~ OrderedListRegexp
+ check_assignment_or_regexp(:ordered_list, OrderedListRegexp)
end
def strip_ordered_list_tag
@@ -79,7 +79,7 @@ module Orgmode
def table_row?
# for an org-mode table, the first non-whitespace character is a
# | (pipe).
- @line =~ /^\s*\|/
+ check_assignment_or_regexp(:table_row, /^\s*\|/)
end
def table_separator?
@@ -87,7 +87,7 @@ module Orgmode
# character as a | (pipe), then consists of nothing else other
# than pipes, hyphens, and pluses.
- @line =~ /^\s*\|[-\|\+]*\s*$/
+ check_assignment_or_regexp(:table_separator, /^\s*\|[-\|\+]*\s*$/)
end
def table?
@@ -110,7 +110,6 @@ module Orgmode
# Determines the paragraph type of the current line.
def paragraph_type
- return @assigned_paragraph_type if @assigned_paragraph_type
return :blank if blank?
return :ordered_list if ordered_list?
return :unordered_list if unordered_list?
@@ -183,5 +182,29 @@ module Orgmode
output_buffer.pop_mode until output_buffer.current_mode == :normal
output_buffer.output
end
+
+ ######################################################################
+ private
+
+ # This function is an internal helper for determining the paragraph
+ # type of a line... for instance, if the line is a comment or contains
+ # metadata. It's used in routines like blank?, plain_list?, etc.
+ #
+ # What's tricky is lines can have assigned types, so you need to check
+ # the assigned type, if present, or see if the characteristic regexp
+ # for the paragraph type matches if not present.
+ #
+ # call-seq:
+ # check_assignment_or_regexp(assignment, regexp) => boolean
+ #
+ # assignment:: if the paragraph has an assigned type, it will be
+ # checked to see if it equals +assignment+.
+ # regexp:: If the paragraph does not have an assigned type,
+ # the contents of the paragraph will be checked against
+ # this regexp.
+ def check_assignment_or_regexp(assignment, regexp)
+ return @assigned_paragraph_type == assignment if @assigned_paragraph_type
+ return @line =~ regexp
+ end
end # class Line
end # module Orgmode
diff --git a/lib/org-ruby/parser.rb b/lib/org-ruby/parser.rb
index d8df6e8..5ff542c 100644
--- a/lib/org-ruby/parser.rb
+++ b/lib/org-ruby/parser.rb
@@ -32,20 +32,42 @@ module Orgmode
@headlines = Array.new
@current_headline = nil
@header_lines = []
+ mode = :normal
@lines.each do |line|
- if (Headline.headline? line) then
- @current_headline = Headline.new line
- @headlines << @current_headline
- else
+ case mode
+ when :normal
+
+ if (Headline.headline? line) then
+ @current_headline = Headline.new line
+ @headlines << @current_headline
+ else
+ line = Line.new line
+ mode = :code if line.begin_block? and line.block_type == "EXAMPLE"
+ if (@current_headline) then
+ @current_headline.body_lines << line
+ else
+ @header_lines << line
+ end
+ end
+
+ when :code
+
+ # As long as we stay in code mode, force lines to be either blank or paragraphs.
+ # Don't try to interpret structural items, like headings and tables.
line = Line.new line
+ if line.end_block? and line.block_type == "EXAMPLE"
+ mode = :normal
+ else
+ line.assigned_paragraph_type = :paragraph unless line.blank?
+ end
if (@current_headline) then
@current_headline.body_lines << line
else
@header_lines << line
end
- end
+ end # case
end
- end # initialize
+ end # initialize
# Creates a new parser from the data in a given file
def self.load(fname)
diff --git a/spec/html_examples/metadata-comment.org-fail b/spec/html_examples/metadata-comment.html
similarity index 73%
copy from spec/html_examples/metadata-comment.org-fail
copy to spec/html_examples/metadata-comment.html
index 36d24ef..562ab63 100644
--- a/spec/html_examples/metadata-comment.org-fail
+++ b/spec/html_examples/metadata-comment.html
@@ -1,15 +1,13 @@
-* Metadata, etc.
+<h1 class="title">Metadata, etc.</h1>
+<p>I normally filter out things that look like metadata. Can’t do it any more. I need to see all of the following:</p>
+<pre>
-I normally filter out things that look like metadata. Can't do it any
-more. I need to see all of the following:
-
-#+BEGIN_EXAMPLE
* DONE Handle inline formatting
CLOSED: [2009-12-26 Sat 21:41]
:PROPERTIES:
:ARCHIVE_TIME: 2009-12-26 Sat 22:16
:ARCHIVE_FILE: ~/brians-brain/content/projects/orgmode_parser.org
- :ARCHIVE_OLPATH: <%= @page.title %>/Future Development
+ :ARCHIVE_OLPATH: <%= @page.title %>/Future Development
:ARCHIVE_CATEGORY: orgmode_parser
:ARCHIVE_TODO: DONE
:END:
@@ -27,4 +25,4 @@ more. I need to see all of the following:
formatting. Which is good, because it means I can copy!
-#+END_EXAMPLE
+</pre>
diff --git a/spec/html_examples/metadata-comment.org-fail b/spec/html_examples/metadata-comment.org
similarity index 100%
rename from spec/html_examples/metadata-comment.org-fail
rename to spec/html_examples/metadata-comment.org
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-ruby-extras/ruby-org.git
More information about the Pkg-ruby-extras-commits
mailing list