Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add //embed{...//} and @<embed>{...} #751

Merged
merged 2 commits into from
Feb 21, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 36 additions & 1 deletion doc/format.md
Original file line number Diff line number Diff line change
Expand Up @@ -688,7 +688,9 @@ Usage:

## Raw Data Block

When you want to write non-Re:VIEW line, use `//raw`.
When you want to write non-Re:VIEW line, use `//raw` or `//embed`.

### `//raw` block

Usage:

Expand All @@ -715,6 +717,39 @@ this is a special line.

Note: `//raw` and `@<raw>` may break structured document easily.

### `//embed` block

Usage:

```
//embed{
<div class="special">
this is a special line.
</div>
//}

//embed[html,markdown]{
<div class="special">
this is a special line.
</div>
//}
```

In above line, `html` and `markdown` is a builder name that handle raw data.

Output:

(In HTML:)

```
<div class="special">
this is a special line.
</div>
```

(In other formats, it is just ignored.)


## Inline Commands

### Styles
Expand Down
27 changes: 27 additions & 0 deletions lib/review/builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,20 @@ def raw(str)
end
end

def embed(lines, arg = nil)
if arg
builders = arg.gsub(/^\s*\|/, "").gsub(/\|\s*$/, "").gsub(/\s/, "").split(/,/)
c = target_name
if builders.include?(c)
print lines.join()
else
""
end
else
print lines.join()
end
end

def warn(msg)
$stderr.puts "#{@location}: warning: #{msg}"
end
Expand Down Expand Up @@ -478,6 +492,19 @@ def inline_raw(args)
end
end

def inline_embed(args)
if matched = args.match(/\|(.*?)\|(.*)/)
builders = matched[1].split(/,/).map{|i| i.gsub(/\s/, '') }
if builders.include?(target_name)
matched[2]
else
""
end
else
args
end
end

## override TextUtils::detab
def detab(str, num = nil)
if num
Expand Down
19 changes: 13 additions & 6 deletions lib/review/compiler.rb
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ def inline_defined?(name)
defblock :tip, 0..1
defblock :box, 0..1
defblock :comment, 0..1, true
defblock :embed, 0..1

defsingle :footnote, 2
defsingle :noindent, 0
Expand Down Expand Up @@ -230,11 +231,12 @@ def inline_defined?(name)
definline :comment
definline :include
definline :tcy
definline :embed

private

def do_compile
f = LineInput.new(Preprocessor::Strip.new(StringIO.new(@chapter.content)))
f = LineInput.new(StringIO.new(@chapter.content))
@strategy.bind self, @chapter, Location.new(@chapter.basename, f)
tagged_section_init
while f.next?
Expand Down Expand Up @@ -266,7 +268,7 @@ def do_compile
warn "`//' seen but is not valid command: #{line.strip.inspect}"
if block_open?(line)
warn "skipping block..."
read_block(f)
read_block(f, false)
end
else
if f.peek.strip.empty?
Expand Down Expand Up @@ -432,21 +434,26 @@ def compile_paragraph(f)
def read_command(f)
line = f.gets
name = line.slice(/[a-z]+/).to_sym
ignore_inline = (name == :embed)
args = parse_args(line.sub(%r<\A//[a-z]+>, '').rstrip.chomp('{'), name)
lines = block_open?(line) ? read_block(f) : nil
lines = block_open?(line) ? read_block(f, ignore_inline) : nil
return name, args, lines
end

def block_open?(line)
line.rstrip[-1,1] == '{'
end

def read_block(f)
def read_block(f, ignore_inline)
head = f.lineno
buf = []
f.until_match(%r<\A//\}>) do |line|
unless line =~ /\A\#@/
buf.push text(line.rstrip)
if ignore_inline
buf.push line
else
unless line =~ /\A\#@/
buf.push text(line.rstrip)
end
end
end
unless %r<\A//\}> =~ f.peek
Expand Down
99 changes: 99 additions & 0 deletions test/test_htmlbuilder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1322,6 +1322,63 @@ def test_inline_raw5
assert_equal "nor\nmal", compile_inline("@<raw>{|html|nor\\nmal}")
end

def test_inline_embed0
assert_equal "normal", compile_inline("@<embed>{normal}")
end

def test_inline_embed1
assert_equal "body", compile_inline("@<embed>{|html|body}")
end

def test_inline_embed3
assert_equal "", compile_inline("@<embed>{|idgxml, latex|body}")
end

def test_inline_embed5
assert_equal 'nor\\nmal', compile_inline("@<embed>{|html|nor\\nmal}")
end

def test_inline_embed_math1
assert_equal '\[ \frac{\partial f}{\partial x} =x^2+xy \]', compile_inline('@<embed>{\[ \frac{\partial f\}{\partial x\} =x^2+xy \]}')
end

def test_inline_embed_math1a
assert_equal '\[ \frac{\partial f}{\partial x} =x^2+xy \]', compile_inline('@<embed>{\\[ \\frac{\\partial f\}{\\partial x\} =x^2+xy \\]}')
end

def test_inline_embed_math1b
assert_equal '\[ \frac{\partial f}{\partial x} =x^2+xy \]', compile_inline('@<embed>{\\\\[ \\\\frac{\\\\partial f\}{\\\\partial x\} =x^2+xy \\\\]}')
end

def test_inline_embed_math1c
assert_equal '\\[ \\frac{}{} \\]',
compile_inline('@<embed>{\[ \\frac{\}{\} \\]}')
end

def test_inline_embed_n1
assert_equal '\\n', compile_inline('@<embed>{\\n}')
end

def test_inline_embed_n2
assert_equal '\\n', compile_inline('@<embed>{\\\\n}')
end

def test_inline_embed_brace_right0
assert_equal '}', compile_inline('@<embed>{\\}}')
end

def test_inline_embed_brace_right1
assert_equal '\\}', compile_inline('@<embed>{\\\\}}')
end

def test_inline_embed_brace_right2
assert_equal '\\}', compile_inline('@<embed>{\\\\\\}}')
end

def test_inline_embed_brace_right3
assert_equal '\\\\}', compile_inline('@<embed>{\\\\\\\\}}')
end

def test_block_raw0
actual = compile_block("//raw[<>!\"\\n& ]\n")
expected = %Q(<>!\"\n& )
Expand Down Expand Up @@ -1352,6 +1409,48 @@ def test_block_raw4
assert_equal expected, actual
end

def test_embed0
lines = '//embed{' + "\n" +
' <>!\\"\\\\n& ' + "\n" +
'//}' + "\n"
actual = compile_block(lines)
expected = ' <>!\\"\\\\n& ' + "\n"
assert_equal expected, actual
end

def test_embed1
actual = compile_block("//embed[|html|]{\n" +
"<>!\\\"\\\\n& \n" +
"//}\n")
expected = %Q(<>!\\\"\\\\n& \n)
assert_equal expected, actual
end

def test_embed2
actual = compile_block("//embed[html, latex]{\n" +
"<>!\\\"\\\\n& \n" +
"//}\n")
expected = %Q(<>!\\\"\\\\n& \n)
assert_equal expected, actual
end

def test_embed2a
actual = compile_block("//embed[|html, latex|]{\n" +
"<>!\\\"\\\\n& \n" +
"//}\n")
expected = %Q(<>!\\\"\\\\n& \n)
assert_equal expected, actual
end

def test_embed2b
actual = compile_block("//embed[html, latex]{\n" +
'#@# comments are not ignored in //embed block' + "\n" +
"<>!\\\"\\\\n& \n" +
"//}\n")
expected = '#@# comments are not ignored in //embed block' + "\n" + %Q(<>!\\\"\\\\n& \n)
assert_equal expected, actual
end

def test_inline_fn
fn = Book::FootnoteIndex.parse(['//footnote[foo][bar\\a\\$buz]'])
@chapter.instance_eval{@footnote_index=fn}
Expand Down