| /******************************************************************************* |
| * Copyright (c) 2007, 2012 David Green and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * David Green - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.mylyn.wikitext.mediawiki.internal.token; |
| |
| import java.util.regex.Matcher; |
| import java.util.regex.Pattern; |
| |
| import org.eclipse.mylyn.wikitext.mediawiki.MediaWikiLanguage; |
| import org.eclipse.mylyn.wikitext.parser.Attributes; |
| import org.eclipse.mylyn.wikitext.parser.DocumentBuilder.BlockType; |
| import org.eclipse.mylyn.wikitext.parser.ImageAttributes; |
| import org.eclipse.mylyn.wikitext.parser.ImageAttributes.Align; |
| import org.eclipse.mylyn.wikitext.parser.LinkAttributes; |
| import org.eclipse.mylyn.wikitext.parser.markup.PatternBasedElement; |
| import org.eclipse.mylyn.wikitext.parser.markup.PatternBasedElementProcessor; |
| |
| /** |
| * match [[Image:someImage.png]] or [[File:someImage.png]] |
| * |
| * @see <a href="http://en.wikipedia.org/wiki/Wikipedia:Images">Images</a> |
| * @see <a href="http://en.wikipedia.org/wiki/Wikipedia:Extended_image_syntax">Extended image syntax</a> |
| * @author David Green |
| */ |
| public class ImageReplacementToken extends PatternBasedElement { |
| |
| private static Pattern widthHeightPart = Pattern.compile("(\\d+)(x(\\d+))?px"); //$NON-NLS-1$ |
| |
| private static Pattern altPattern = Pattern.compile("\\s*alt\\s*=\\s*(.+)"); //$NON-NLS-1$ |
| |
| @Override |
| protected String getPattern(int groupOffset) { |
| return "(?:\\[\\[(?:[Ii]mage|[Ff]ile):\\s*([^\\]\\|]+)(?:\\|(([^\\[\\]]|(\\[\\[[^\\[\\]]+\\]\\]))*))?\\]\\])"; //$NON-NLS-1$ |
| } |
| |
| @Override |
| protected int getPatternGroupCount() { |
| return 4; |
| } |
| |
| @Override |
| protected PatternBasedElementProcessor newProcessor() { |
| return new ImageReplacementTokenProcessor(); |
| } |
| |
| private static class ImageReplacementTokenProcessor extends PatternBasedElementProcessor { |
| |
| @Override |
| public MediaWikiLanguage getMarkupLanguage() { |
| return (MediaWikiLanguage) super.getMarkupLanguage(); |
| } |
| |
| @Override |
| public void emit() { |
| String imageUrl = group(1); |
| if (imageUrl.indexOf('/') == -1) { |
| // images hosted on the wiki should have spaces removed from their name |
| // this may seem a little odd but there's an issue here: files can be uploaded |
| // to the wiki with a name that differs from the URL. Page authors can use |
| // either name in the wiki markup, and there's no way to know what they've used. |
| // to be safe we always replace space with underscore, and do the same in |
| // the image fetching strategy. |
| imageUrl = imageUrl.replace(' ', '_'); |
| } |
| imageUrl = getMarkupLanguage().mapImageName(imageUrl); |
| |
| String optionsString = group(2); |
| |
| boolean thumbnail = false; |
| |
| ImageAttributes attributes = new ImageAttributes(); |
| if (optionsString != null) { |
| Matcher matcher; |
| String[] options = optionsString.split("\\s*\\|\\s*"); //$NON-NLS-1$ |
| for (int optionIndex = 0; optionIndex < options.length; ++optionIndex) { |
| String option = options[optionIndex]; |
| if ("center".equals(option)) { //$NON-NLS-1$ |
| attributes.setAlign(Align.Middle); |
| } else if ("left".equals(option)) { //$NON-NLS-1$ |
| attributes.setAlign(Align.Left); |
| } else if ("right".equals(option)) { //$NON-NLS-1$ |
| attributes.setAlign(Align.Right); |
| } else if ("none".equals(option)) { //$NON-NLS-1$ |
| attributes.setAlign(null); |
| } else if ("thumb".equals(option) || "thumbnail".equals(option)) { //$NON-NLS-1$ //$NON-NLS-2$ |
| thumbnail = true; |
| } else if ((matcher = widthHeightPart.matcher(option)).matches()) { |
| try { |
| String sizePart = matcher.group(1); |
| String heightPart = matcher.group(3); |
| int size = Integer.parseInt(sizePart); |
| attributes.setWidth(size); |
| if (heightPart != null) { |
| int height = Integer.parseInt(heightPart); |
| attributes.setHeight(height); |
| } |
| } catch (NumberFormatException e) { |
| // ignore |
| } |
| } else if ("frameless".equals(option)) { //$NON-NLS-1$ |
| attributes.setBorder(0); |
| } else if ("frame".equals(option)) { //$NON-NLS-1$ |
| attributes.setBorder(1); |
| } else { |
| Matcher altMatcher = altPattern.matcher(option); |
| if (altMatcher.matches()) { |
| attributes.setAlt(altMatcher.group(1)); |
| } else { |
| if (optionIndex == options.length - 1) { |
| // the last one is a caption |
| attributes.setTitle(option); |
| } else { |
| // if not the last one, then it's alt text |
| attributes.setAlt(option); |
| } |
| } |
| } |
| } |
| } |
| if (thumbnail) { |
| // we want to generate something like this: |
| // <div class="thumb tleft"> |
| // <div class="thumbinner" style="width:182px;"><a href="/wiki/File:Example.jpg" |
| // class="image"><img alt="" |
| // src="http://upload.wikimedia.org/wikipedia/mediawiki/thumb/a/a9/Example.jpg/180px-Example.jpg" |
| // width="180" height="120" class="thumbimage" /></a> |
| // <div class="thumbcaption"> |
| // <div class="magnify"><a href="/wiki/File:Example.jpg" class="internal" |
| // title="Enlarge"><img src="/skins-1.5/common/images/magnify-clip.png" width="15" |
| // height="11" alt="" /></a></div> |
| // Official logo of the <a |
| // href="/w/index.php?title=International_Floorball_Federation&action=edit&redlink=1" |
| // class="new" title="International Floorball Federation (page does not |
| // exist)">International Floorball Federation</a>, floorball's governing |
| // body.</div> |
| // </div> |
| // </div> |
| |
| String caption = attributes.getTitle(); |
| attributes.setTitle(null); |
| |
| Attributes outerDivAttributes = new Attributes(null, "thumb", null, null); //$NON-NLS-1$ |
| if (attributes.getAlign() != null) { |
| outerDivAttributes.appendCssClass(attributes.getAlign().name().toLowerCase()); |
| } |
| builder.beginBlock(BlockType.DIV, outerDivAttributes); |
| |
| final Attributes thumbInnerDivAttributes = new Attributes( |
| null, |
| "thumbinner", attributes.getWidth() > 0 ? String.format("width:%spx;", attributes.getWidth() + 2) : null, null); //$NON-NLS-1$ //$NON-NLS-2$ |
| builder.beginBlock(BlockType.DIV, thumbInnerDivAttributes); |
| //FIXME: image |
| LinkAttributes linkAttributes = new LinkAttributes(); |
| linkAttributes.setCssClass("image"); //$NON-NLS-1$ |
| |
| attributes.appendCssClass("thumbimage"); //$NON-NLS-1$ |
| builder.imageLink(linkAttributes, attributes, imageUrl, imageUrl); |
| |
| if (caption != null) { |
| builder.beginBlock(BlockType.DIV, new Attributes(null, "thumbcaption", null, null)); //$NON-NLS-1$ |
| markupLanguage.emitMarkupText(parser, state, caption); |
| builder.endBlock(); // div |
| } |
| |
| builder.endBlock(); // div |
| builder.endBlock(); // div |
| |
| } else { |
| builder.image(attributes, imageUrl); |
| } |
| } |
| } |
| |
| } |